diff options
author | David S. Miller <davem@davemloft.net> | 2015-03-19 15:18:04 -0400 |
---|---|---|
committer | David S. Miller <davem@davemloft.net> | 2015-03-19 15:18:04 -0400 |
commit | 970282d0e1404b23f9d7ec6a676fa76ff15b3376 (patch) | |
tree | 15b7398383f5158cd19ba5fcbf17d46509e80a86 | |
parent | c9bdc0dde187e5f6b481989b4084c1b7cbe2726f (diff) | |
parent | ea6edfbcefec1fcfdb826a1d5a054f402dfbfb24 (diff) |
Merge branch 'for-upstream' of git://git.kernel.org/pub/scm/linux/kernel/git/bluetooth/bluetooth-next
Johan Hedberg says:
====================
pull request: bluetooth-next 2015-03-19
This wont the last 4.1 bluetooth-next pull request, but we've piled up
enough patches in less than a week that I wanted to save you from a
single huge "last-minute" pull somewhere closer to the merge window.
The main changes are:
- Simultaneous LE & BR/EDR discovery support for HW that can do it
- Complete LE OOB pairing support
- More fine-grained mgmt-command access control (normal user can now do
harmless read-only operations).
- Added RF power amplifier support in cc2520 ieee802154 driver
- Some cleanups/fixes in ieee802154 code
Please let me know if there are any issues pulling. Thanks.
====================
Signed-off-by: David S. Miller <davem@davemloft.net>
-rw-r--r-- | Documentation/devicetree/bindings/net/ieee802154/cc2520.txt | 4 | ||||
-rw-r--r-- | drivers/bluetooth/btusb.c | 8 | ||||
-rw-r--r-- | drivers/net/ieee802154/at86rf230.c | 2 | ||||
-rw-r--r-- | drivers/net/ieee802154/cc2520.c | 150 | ||||
-rw-r--r-- | include/linux/spi/cc2520.h | 1 | ||||
-rw-r--r-- | include/net/bluetooth/bluetooth.h | 5 | ||||
-rw-r--r-- | include/net/bluetooth/hci.h | 22 | ||||
-rw-r--r-- | include/net/bluetooth/hci_core.h | 14 | ||||
-rw-r--r-- | include/net/bluetooth/mgmt.h | 50 | ||||
-rw-r--r-- | net/bluetooth/Makefile | 2 | ||||
-rw-r--r-- | net/bluetooth/hci_core.c | 24 | ||||
-rw-r--r-- | net/bluetooth/hci_debugfs.c | 2 | ||||
-rw-r--r-- | net/bluetooth/hci_event.c | 78 | ||||
-rw-r--r-- | net/bluetooth/hci_sock.c | 180 | ||||
-rw-r--r-- | net/bluetooth/mgmt.c | 1037 | ||||
-rw-r--r-- | net/bluetooth/mgmt_util.c | 210 | ||||
-rw-r--r-- | net/bluetooth/mgmt_util.h | 53 | ||||
-rw-r--r-- | net/bluetooth/smp.c | 278 | ||||
-rw-r--r-- | net/bluetooth/smp.h | 1 | ||||
-rw-r--r-- | net/mac802154/driver-ops.h | 4 |
20 files changed, 1485 insertions, 640 deletions
diff --git a/Documentation/devicetree/bindings/net/ieee802154/cc2520.txt b/Documentation/devicetree/bindings/net/ieee802154/cc2520.txt index 0071883c08d8..fb6d49f184ed 100644 --- a/Documentation/devicetree/bindings/net/ieee802154/cc2520.txt +++ b/Documentation/devicetree/bindings/net/ieee802154/cc2520.txt | |||
@@ -13,11 +13,15 @@ Required properties: | |||
13 | - cca-gpio: GPIO spec for the CCA pin | 13 | - cca-gpio: GPIO spec for the CCA pin |
14 | - vreg-gpio: GPIO spec for the VREG pin | 14 | - vreg-gpio: GPIO spec for the VREG pin |
15 | - reset-gpio: GPIO spec for the RESET pin | 15 | - reset-gpio: GPIO spec for the RESET pin |
16 | Optional properties: | ||
17 | - amplified: include if the CC2520 is connected to a CC2591 amplifier | ||
18 | |||
16 | Example: | 19 | Example: |
17 | cc2520@0 { | 20 | cc2520@0 { |
18 | compatible = "ti,cc2520"; | 21 | compatible = "ti,cc2520"; |
19 | reg = <0>; | 22 | reg = <0>; |
20 | spi-max-frequency = <4000000>; | 23 | spi-max-frequency = <4000000>; |
24 | amplified; | ||
21 | pinctrl-names = "default"; | 25 | pinctrl-names = "default"; |
22 | pinctrl-0 = <&cc2520_cape_pins>; | 26 | pinctrl-0 = <&cc2520_cape_pins>; |
23 | fifo-gpio = <&gpio1 18 0>; | 27 | fifo-gpio = <&gpio1 18 0>; |
diff --git a/drivers/bluetooth/btusb.c b/drivers/bluetooth/btusb.c index 6fa9338745cf..708b6574d805 100644 --- a/drivers/bluetooth/btusb.c +++ b/drivers/bluetooth/btusb.c | |||
@@ -215,8 +215,8 @@ static const struct usb_device_id blacklist_table[] = { | |||
215 | { USB_DEVICE(0x0489, 0xe03c), .driver_info = BTUSB_ATH3012 }, | 215 | { USB_DEVICE(0x0489, 0xe03c), .driver_info = BTUSB_ATH3012 }, |
216 | 216 | ||
217 | /* QCA ROME chipset */ | 217 | /* QCA ROME chipset */ |
218 | { USB_DEVICE(0x0cf3, 0xe300), .driver_info = BTUSB_QCA_ROME}, | 218 | { USB_DEVICE(0x0cf3, 0xe300), .driver_info = BTUSB_QCA_ROME }, |
219 | { USB_DEVICE(0x0cf3, 0xe360), .driver_info = BTUSB_QCA_ROME}, | 219 | { USB_DEVICE(0x0cf3, 0xe360), .driver_info = BTUSB_QCA_ROME }, |
220 | 220 | ||
221 | /* Broadcom BCM2035 */ | 221 | /* Broadcom BCM2035 */ |
222 | { USB_DEVICE(0x0a5c, 0x2009), .driver_info = BTUSB_BCM92035 }, | 222 | { USB_DEVICE(0x0a5c, 0x2009), .driver_info = BTUSB_BCM92035 }, |
@@ -3019,6 +3019,7 @@ static int btusb_probe(struct usb_interface *intf, | |||
3019 | hdev->shutdown = btusb_shutdown_intel; | 3019 | hdev->shutdown = btusb_shutdown_intel; |
3020 | hdev->set_bdaddr = btusb_set_bdaddr_intel; | 3020 | hdev->set_bdaddr = btusb_set_bdaddr_intel; |
3021 | set_bit(HCI_QUIRK_STRICT_DUPLICATE_FILTER, &hdev->quirks); | 3021 | set_bit(HCI_QUIRK_STRICT_DUPLICATE_FILTER, &hdev->quirks); |
3022 | set_bit(HCI_QUIRK_SIMULTANEOUS_DISCOVERY, &hdev->quirks); | ||
3022 | } | 3023 | } |
3023 | 3024 | ||
3024 | if (id->driver_info & BTUSB_INTEL_NEW) { | 3025 | if (id->driver_info & BTUSB_INTEL_NEW) { |
@@ -3042,6 +3043,7 @@ static int btusb_probe(struct usb_interface *intf, | |||
3042 | 3043 | ||
3043 | if (id->driver_info & BTUSB_ATH3012) { | 3044 | if (id->driver_info & BTUSB_ATH3012) { |
3044 | hdev->set_bdaddr = btusb_set_bdaddr_ath3012; | 3045 | hdev->set_bdaddr = btusb_set_bdaddr_ath3012; |
3046 | set_bit(HCI_QUIRK_SIMULTANEOUS_DISCOVERY, &hdev->quirks); | ||
3045 | set_bit(HCI_QUIRK_STRICT_DUPLICATE_FILTER, &hdev->quirks); | 3047 | set_bit(HCI_QUIRK_STRICT_DUPLICATE_FILTER, &hdev->quirks); |
3046 | } | 3048 | } |
3047 | 3049 | ||
@@ -3085,6 +3087,8 @@ static int btusb_probe(struct usb_interface *intf, | |||
3085 | /* Fake CSR devices with broken commands */ | 3087 | /* Fake CSR devices with broken commands */ |
3086 | if (bcdDevice <= 0x100) | 3088 | if (bcdDevice <= 0x100) |
3087 | hdev->setup = btusb_setup_csr; | 3089 | hdev->setup = btusb_setup_csr; |
3090 | |||
3091 | set_bit(HCI_QUIRK_SIMULTANEOUS_DISCOVERY, &hdev->quirks); | ||
3088 | } | 3092 | } |
3089 | 3093 | ||
3090 | if (id->driver_info & BTUSB_SNIFFER) { | 3094 | if (id->driver_info & BTUSB_SNIFFER) { |
diff --git a/drivers/net/ieee802154/at86rf230.c b/drivers/net/ieee802154/at86rf230.c index b64c5c7b2a50..cc5efa149da1 100644 --- a/drivers/net/ieee802154/at86rf230.c +++ b/drivers/net/ieee802154/at86rf230.c | |||
@@ -325,7 +325,7 @@ at86rf230_read_subreg(struct at86rf230_local *lp, | |||
325 | int rc; | 325 | int rc; |
326 | 326 | ||
327 | rc = __at86rf230_read(lp, addr, data); | 327 | rc = __at86rf230_read(lp, addr, data); |
328 | if (rc > 0) | 328 | if (!rc) |
329 | *data = (*data & mask) >> shift; | 329 | *data = (*data & mask) >> shift; |
330 | 330 | ||
331 | return rc; | 331 | return rc; |
diff --git a/drivers/net/ieee802154/cc2520.c b/drivers/net/ieee802154/cc2520.c index 181b349b060e..f833b8bb6663 100644 --- a/drivers/net/ieee802154/cc2520.c +++ b/drivers/net/ieee802154/cc2520.c | |||
@@ -714,11 +714,45 @@ static irqreturn_t cc2520_sfd_isr(int irq, void *data) | |||
714 | return IRQ_HANDLED; | 714 | return IRQ_HANDLED; |
715 | } | 715 | } |
716 | 716 | ||
717 | static int cc2520_get_platform_data(struct spi_device *spi, | ||
718 | struct cc2520_platform_data *pdata) | ||
719 | { | ||
720 | struct device_node *np = spi->dev.of_node; | ||
721 | struct cc2520_private *priv = spi_get_drvdata(spi); | ||
722 | |||
723 | if (!np) { | ||
724 | struct cc2520_platform_data *spi_pdata = spi->dev.platform_data; | ||
725 | if (!spi_pdata) | ||
726 | return -ENOENT; | ||
727 | *pdata = *spi_pdata; | ||
728 | return 0; | ||
729 | } | ||
730 | |||
731 | pdata->fifo = of_get_named_gpio(np, "fifo-gpio", 0); | ||
732 | priv->fifo_pin = pdata->fifo; | ||
733 | |||
734 | pdata->fifop = of_get_named_gpio(np, "fifop-gpio", 0); | ||
735 | |||
736 | pdata->sfd = of_get_named_gpio(np, "sfd-gpio", 0); | ||
737 | pdata->cca = of_get_named_gpio(np, "cca-gpio", 0); | ||
738 | pdata->vreg = of_get_named_gpio(np, "vreg-gpio", 0); | ||
739 | pdata->reset = of_get_named_gpio(np, "reset-gpio", 0); | ||
740 | |||
741 | pdata->amplified = of_property_read_bool(np, "amplified"); | ||
742 | |||
743 | return 0; | ||
744 | } | ||
745 | |||
717 | static int cc2520_hw_init(struct cc2520_private *priv) | 746 | static int cc2520_hw_init(struct cc2520_private *priv) |
718 | { | 747 | { |
719 | u8 status = 0, state = 0xff; | 748 | u8 status = 0, state = 0xff; |
720 | int ret; | 749 | int ret; |
721 | int timeout = 100; | 750 | int timeout = 100; |
751 | struct cc2520_platform_data pdata; | ||
752 | |||
753 | ret = cc2520_get_platform_data(priv->spi, &pdata); | ||
754 | if (ret) | ||
755 | goto err_ret; | ||
722 | 756 | ||
723 | ret = cc2520_read_register(priv, CC2520_FSMSTAT1, &state); | 757 | ret = cc2520_read_register(priv, CC2520_FSMSTAT1, &state); |
724 | if (ret) | 758 | if (ret) |
@@ -741,11 +775,47 @@ static int cc2520_hw_init(struct cc2520_private *priv) | |||
741 | 775 | ||
742 | dev_vdbg(&priv->spi->dev, "oscillator brought up\n"); | 776 | dev_vdbg(&priv->spi->dev, "oscillator brought up\n"); |
743 | 777 | ||
744 | /* Registers default value: section 28.1 in Datasheet */ | 778 | /* If the CC2520 is connected to a CC2591 amplifier, we must both |
745 | ret = cc2520_write_register(priv, CC2520_TXPOWER, 0xF7); | 779 | * configure GPIOs on the CC2520 to correctly configure the CC2591 |
746 | if (ret) | 780 | * and change a couple settings of the CC2520 to work with the |
747 | goto err_ret; | 781 | * amplifier. See section 8 page 17 of TI application note AN065. |
782 | * http://www.ti.com/lit/an/swra229a/swra229a.pdf | ||
783 | */ | ||
784 | if (pdata.amplified) { | ||
785 | ret = cc2520_write_register(priv, CC2520_TXPOWER, 0xF9); | ||
786 | if (ret) | ||
787 | goto err_ret; | ||
788 | |||
789 | ret = cc2520_write_register(priv, CC2520_AGCCTRL1, 0x16); | ||
790 | if (ret) | ||
791 | goto err_ret; | ||
792 | |||
793 | ret = cc2520_write_register(priv, CC2520_GPIOCTRL0, 0x46); | ||
794 | if (ret) | ||
795 | goto err_ret; | ||
796 | |||
797 | ret = cc2520_write_register(priv, CC2520_GPIOCTRL5, 0x47); | ||
798 | if (ret) | ||
799 | goto err_ret; | ||
800 | |||
801 | ret = cc2520_write_register(priv, CC2520_GPIOPOLARITY, 0x1e); | ||
802 | if (ret) | ||
803 | goto err_ret; | ||
804 | |||
805 | ret = cc2520_write_register(priv, CC2520_TXCTRL, 0xc1); | ||
806 | if (ret) | ||
807 | goto err_ret; | ||
808 | } else { | ||
809 | ret = cc2520_write_register(priv, CC2520_TXPOWER, 0xF7); | ||
810 | if (ret) | ||
811 | goto err_ret; | ||
748 | 812 | ||
813 | ret = cc2520_write_register(priv, CC2520_AGCCTRL1, 0x11); | ||
814 | if (ret) | ||
815 | goto err_ret; | ||
816 | } | ||
817 | |||
818 | /* Registers default value: section 28.1 in Datasheet */ | ||
749 | ret = cc2520_write_register(priv, CC2520_CCACTRL0, 0x1A); | 819 | ret = cc2520_write_register(priv, CC2520_CCACTRL0, 0x1A); |
750 | if (ret) | 820 | if (ret) |
751 | goto err_ret; | 821 | goto err_ret; |
@@ -770,10 +840,6 @@ static int cc2520_hw_init(struct cc2520_private *priv) | |||
770 | if (ret) | 840 | if (ret) |
771 | goto err_ret; | 841 | goto err_ret; |
772 | 842 | ||
773 | ret = cc2520_write_register(priv, CC2520_AGCCTRL1, 0x11); | ||
774 | if (ret) | ||
775 | goto err_ret; | ||
776 | |||
777 | ret = cc2520_write_register(priv, CC2520_ADCTEST0, 0x10); | 843 | ret = cc2520_write_register(priv, CC2520_ADCTEST0, 0x10); |
778 | if (ret) | 844 | if (ret) |
779 | goto err_ret; | 845 | goto err_ret; |
@@ -808,40 +874,10 @@ err_ret: | |||
808 | return ret; | 874 | return ret; |
809 | } | 875 | } |
810 | 876 | ||
811 | static struct cc2520_platform_data * | ||
812 | cc2520_get_platform_data(struct spi_device *spi) | ||
813 | { | ||
814 | struct cc2520_platform_data *pdata; | ||
815 | struct device_node *np = spi->dev.of_node; | ||
816 | struct cc2520_private *priv = spi_get_drvdata(spi); | ||
817 | |||
818 | if (!np) | ||
819 | return spi->dev.platform_data; | ||
820 | |||
821 | pdata = devm_kzalloc(&spi->dev, sizeof(*pdata), GFP_KERNEL); | ||
822 | if (!pdata) | ||
823 | goto done; | ||
824 | |||
825 | pdata->fifo = of_get_named_gpio(np, "fifo-gpio", 0); | ||
826 | priv->fifo_pin = pdata->fifo; | ||
827 | |||
828 | pdata->fifop = of_get_named_gpio(np, "fifop-gpio", 0); | ||
829 | |||
830 | pdata->sfd = of_get_named_gpio(np, "sfd-gpio", 0); | ||
831 | pdata->cca = of_get_named_gpio(np, "cca-gpio", 0); | ||
832 | pdata->vreg = of_get_named_gpio(np, "vreg-gpio", 0); | ||
833 | pdata->reset = of_get_named_gpio(np, "reset-gpio", 0); | ||
834 | |||
835 | spi->dev.platform_data = pdata; | ||
836 | |||
837 | done: | ||
838 | return pdata; | ||
839 | } | ||
840 | |||
841 | static int cc2520_probe(struct spi_device *spi) | 877 | static int cc2520_probe(struct spi_device *spi) |
842 | { | 878 | { |
843 | struct cc2520_private *priv; | 879 | struct cc2520_private *priv; |
844 | struct cc2520_platform_data *pdata; | 880 | struct cc2520_platform_data pdata; |
845 | int ret; | 881 | int ret; |
846 | 882 | ||
847 | priv = devm_kzalloc(&spi->dev, sizeof(*priv), GFP_KERNEL); | 883 | priv = devm_kzalloc(&spi->dev, sizeof(*priv), GFP_KERNEL); |
@@ -850,8 +886,8 @@ static int cc2520_probe(struct spi_device *spi) | |||
850 | 886 | ||
851 | spi_set_drvdata(spi, priv); | 887 | spi_set_drvdata(spi, priv); |
852 | 888 | ||
853 | pdata = cc2520_get_platform_data(spi); | 889 | ret = cc2520_get_platform_data(spi, &pdata); |
854 | if (!pdata) { | 890 | if (ret < 0) { |
855 | dev_err(&spi->dev, "no platform data\n"); | 891 | dev_err(&spi->dev, "no platform data\n"); |
856 | return -EINVAL; | 892 | return -EINVAL; |
857 | } | 893 | } |
@@ -869,76 +905,76 @@ static int cc2520_probe(struct spi_device *spi) | |||
869 | init_completion(&priv->tx_complete); | 905 | init_completion(&priv->tx_complete); |
870 | 906 | ||
871 | /* Request all the gpio's */ | 907 | /* Request all the gpio's */ |
872 | if (!gpio_is_valid(pdata->fifo)) { | 908 | if (!gpio_is_valid(pdata.fifo)) { |
873 | dev_err(&spi->dev, "fifo gpio is not valid\n"); | 909 | dev_err(&spi->dev, "fifo gpio is not valid\n"); |
874 | ret = -EINVAL; | 910 | ret = -EINVAL; |
875 | goto err_hw_init; | 911 | goto err_hw_init; |
876 | } | 912 | } |
877 | 913 | ||
878 | ret = devm_gpio_request_one(&spi->dev, pdata->fifo, | 914 | ret = devm_gpio_request_one(&spi->dev, pdata.fifo, |
879 | GPIOF_IN, "fifo"); | 915 | GPIOF_IN, "fifo"); |
880 | if (ret) | 916 | if (ret) |
881 | goto err_hw_init; | 917 | goto err_hw_init; |
882 | 918 | ||
883 | if (!gpio_is_valid(pdata->cca)) { | 919 | if (!gpio_is_valid(pdata.cca)) { |
884 | dev_err(&spi->dev, "cca gpio is not valid\n"); | 920 | dev_err(&spi->dev, "cca gpio is not valid\n"); |
885 | ret = -EINVAL; | 921 | ret = -EINVAL; |
886 | goto err_hw_init; | 922 | goto err_hw_init; |
887 | } | 923 | } |
888 | 924 | ||
889 | ret = devm_gpio_request_one(&spi->dev, pdata->cca, | 925 | ret = devm_gpio_request_one(&spi->dev, pdata.cca, |
890 | GPIOF_IN, "cca"); | 926 | GPIOF_IN, "cca"); |
891 | if (ret) | 927 | if (ret) |
892 | goto err_hw_init; | 928 | goto err_hw_init; |
893 | 929 | ||
894 | if (!gpio_is_valid(pdata->fifop)) { | 930 | if (!gpio_is_valid(pdata.fifop)) { |
895 | dev_err(&spi->dev, "fifop gpio is not valid\n"); | 931 | dev_err(&spi->dev, "fifop gpio is not valid\n"); |
896 | ret = -EINVAL; | 932 | ret = -EINVAL; |
897 | goto err_hw_init; | 933 | goto err_hw_init; |
898 | } | 934 | } |
899 | 935 | ||
900 | ret = devm_gpio_request_one(&spi->dev, pdata->fifop, | 936 | ret = devm_gpio_request_one(&spi->dev, pdata.fifop, |
901 | GPIOF_IN, "fifop"); | 937 | GPIOF_IN, "fifop"); |
902 | if (ret) | 938 | if (ret) |
903 | goto err_hw_init; | 939 | goto err_hw_init; |
904 | 940 | ||
905 | if (!gpio_is_valid(pdata->sfd)) { | 941 | if (!gpio_is_valid(pdata.sfd)) { |
906 | dev_err(&spi->dev, "sfd gpio is not valid\n"); | 942 | dev_err(&spi->dev, "sfd gpio is not valid\n"); |
907 | ret = -EINVAL; | 943 | ret = -EINVAL; |
908 | goto err_hw_init; | 944 | goto err_hw_init; |
909 | } | 945 | } |
910 | 946 | ||
911 | ret = devm_gpio_request_one(&spi->dev, pdata->sfd, | 947 | ret = devm_gpio_request_one(&spi->dev, pdata.sfd, |
912 | GPIOF_IN, "sfd"); | 948 | GPIOF_IN, "sfd"); |
913 | if (ret) | 949 | if (ret) |
914 | goto err_hw_init; | 950 | goto err_hw_init; |
915 | 951 | ||
916 | if (!gpio_is_valid(pdata->reset)) { | 952 | if (!gpio_is_valid(pdata.reset)) { |
917 | dev_err(&spi->dev, "reset gpio is not valid\n"); | 953 | dev_err(&spi->dev, "reset gpio is not valid\n"); |
918 | ret = -EINVAL; | 954 | ret = -EINVAL; |
919 | goto err_hw_init; | 955 | goto err_hw_init; |
920 | } | 956 | } |
921 | 957 | ||
922 | ret = devm_gpio_request_one(&spi->dev, pdata->reset, | 958 | ret = devm_gpio_request_one(&spi->dev, pdata.reset, |
923 | GPIOF_OUT_INIT_LOW, "reset"); | 959 | GPIOF_OUT_INIT_LOW, "reset"); |
924 | if (ret) | 960 | if (ret) |
925 | goto err_hw_init; | 961 | goto err_hw_init; |
926 | 962 | ||
927 | if (!gpio_is_valid(pdata->vreg)) { | 963 | if (!gpio_is_valid(pdata.vreg)) { |
928 | dev_err(&spi->dev, "vreg gpio is not valid\n"); | 964 | dev_err(&spi->dev, "vreg gpio is not valid\n"); |
929 | ret = -EINVAL; | 965 | ret = -EINVAL; |
930 | goto err_hw_init; | 966 | goto err_hw_init; |
931 | } | 967 | } |
932 | 968 | ||
933 | ret = devm_gpio_request_one(&spi->dev, pdata->vreg, | 969 | ret = devm_gpio_request_one(&spi->dev, pdata.vreg, |
934 | GPIOF_OUT_INIT_LOW, "vreg"); | 970 | GPIOF_OUT_INIT_LOW, "vreg"); |
935 | if (ret) | 971 | if (ret) |
936 | goto err_hw_init; | 972 | goto err_hw_init; |
937 | 973 | ||
938 | gpio_set_value(pdata->vreg, HIGH); | 974 | gpio_set_value(pdata.vreg, HIGH); |
939 | usleep_range(100, 150); | 975 | usleep_range(100, 150); |
940 | 976 | ||
941 | gpio_set_value(pdata->reset, HIGH); | 977 | gpio_set_value(pdata.reset, HIGH); |
942 | usleep_range(200, 250); | 978 | usleep_range(200, 250); |
943 | 979 | ||
944 | ret = cc2520_hw_init(priv); | 980 | ret = cc2520_hw_init(priv); |
@@ -947,7 +983,7 @@ static int cc2520_probe(struct spi_device *spi) | |||
947 | 983 | ||
948 | /* Set up fifop interrupt */ | 984 | /* Set up fifop interrupt */ |
949 | ret = devm_request_irq(&spi->dev, | 985 | ret = devm_request_irq(&spi->dev, |
950 | gpio_to_irq(pdata->fifop), | 986 | gpio_to_irq(pdata.fifop), |
951 | cc2520_fifop_isr, | 987 | cc2520_fifop_isr, |
952 | IRQF_TRIGGER_RISING, | 988 | IRQF_TRIGGER_RISING, |
953 | dev_name(&spi->dev), | 989 | dev_name(&spi->dev), |
@@ -959,7 +995,7 @@ static int cc2520_probe(struct spi_device *spi) | |||
959 | 995 | ||
960 | /* Set up sfd interrupt */ | 996 | /* Set up sfd interrupt */ |
961 | ret = devm_request_irq(&spi->dev, | 997 | ret = devm_request_irq(&spi->dev, |
962 | gpio_to_irq(pdata->sfd), | 998 | gpio_to_irq(pdata.sfd), |
963 | cc2520_sfd_isr, | 999 | cc2520_sfd_isr, |
964 | IRQF_TRIGGER_FALLING, | 1000 | IRQF_TRIGGER_FALLING, |
965 | dev_name(&spi->dev), | 1001 | dev_name(&spi->dev), |
diff --git a/include/linux/spi/cc2520.h b/include/linux/spi/cc2520.h index 85b8ee67e937..e741e8baad92 100644 --- a/include/linux/spi/cc2520.h +++ b/include/linux/spi/cc2520.h | |||
@@ -21,6 +21,7 @@ struct cc2520_platform_data { | |||
21 | int sfd; | 21 | int sfd; |
22 | int reset; | 22 | int reset; |
23 | int vreg; | 23 | int vreg; |
24 | bool amplified; | ||
24 | }; | 25 | }; |
25 | 26 | ||
26 | #endif | 27 | #endif |
diff --git a/include/net/bluetooth/bluetooth.h b/include/net/bluetooth/bluetooth.h index e598ca096ec9..33a5e00025aa 100644 --- a/include/net/bluetooth/bluetooth.h +++ b/include/net/bluetooth/bluetooth.h | |||
@@ -335,6 +335,11 @@ out: | |||
335 | 335 | ||
336 | int bt_to_errno(__u16 code); | 336 | int bt_to_errno(__u16 code); |
337 | 337 | ||
338 | void hci_sock_set_flag(struct sock *sk, int nr); | ||
339 | void hci_sock_clear_flag(struct sock *sk, int nr); | ||
340 | int hci_sock_test_flag(struct sock *sk, int nr); | ||
341 | unsigned short hci_sock_get_channel(struct sock *sk); | ||
342 | |||
338 | int hci_sock_init(void); | 343 | int hci_sock_init(void); |
339 | void hci_sock_cleanup(void); | 344 | void hci_sock_cleanup(void); |
340 | 345 | ||
diff --git a/include/net/bluetooth/hci.h b/include/net/bluetooth/hci.h index d942fedbaedd..06e7eee31ce4 100644 --- a/include/net/bluetooth/hci.h +++ b/include/net/bluetooth/hci.h | |||
@@ -160,6 +160,14 @@ enum { | |||
160 | * during the hdev->setup vendor callback. | 160 | * during the hdev->setup vendor callback. |
161 | */ | 161 | */ |
162 | HCI_QUIRK_STRICT_DUPLICATE_FILTER, | 162 | HCI_QUIRK_STRICT_DUPLICATE_FILTER, |
163 | |||
164 | /* When this quirk is set, LE scan and BR/EDR inquiry is done | ||
165 | * simultaneously, otherwise it's interleaved. | ||
166 | * | ||
167 | * This quirk can be set before hci_register_dev is called or | ||
168 | * during the hdev->setup vendor callback. | ||
169 | */ | ||
170 | HCI_QUIRK_SIMULTANEOUS_DISCOVERY, | ||
163 | }; | 171 | }; |
164 | 172 | ||
165 | /* HCI device flags */ | 173 | /* HCI device flags */ |
@@ -179,6 +187,16 @@ enum { | |||
179 | HCI_RESET, | 187 | HCI_RESET, |
180 | }; | 188 | }; |
181 | 189 | ||
190 | /* HCI socket flags */ | ||
191 | enum { | ||
192 | HCI_SOCK_TRUSTED, | ||
193 | HCI_MGMT_INDEX_EVENTS, | ||
194 | HCI_MGMT_UNCONF_INDEX_EVENTS, | ||
195 | HCI_MGMT_EXT_INDEX_EVENTS, | ||
196 | HCI_MGMT_GENERIC_EVENTS, | ||
197 | HCI_MGMT_OOB_DATA_EVENTS, | ||
198 | }; | ||
199 | |||
182 | /* | 200 | /* |
183 | * BR/EDR and/or LE controller flags: the flags defined here should represent | 201 | * BR/EDR and/or LE controller flags: the flags defined here should represent |
184 | * states from the controller. | 202 | * states from the controller. |
@@ -447,6 +465,10 @@ enum { | |||
447 | #define EIR_SSP_HASH_C 0x0E /* Simple Pairing Hash C */ | 465 | #define EIR_SSP_HASH_C 0x0E /* Simple Pairing Hash C */ |
448 | #define EIR_SSP_RAND_R 0x0F /* Simple Pairing Randomizer R */ | 466 | #define EIR_SSP_RAND_R 0x0F /* Simple Pairing Randomizer R */ |
449 | #define EIR_DEVICE_ID 0x10 /* device ID */ | 467 | #define EIR_DEVICE_ID 0x10 /* device ID */ |
468 | #define EIR_LE_BDADDR 0x1B /* LE Bluetooth device address */ | ||
469 | #define EIR_LE_ROLE 0x1C /* LE role */ | ||
470 | #define EIR_LE_SC_CONFIRM 0x22 /* LE SC Confirmation Value */ | ||
471 | #define EIR_LE_SC_RANDOM 0x23 /* LE SC Random Value */ | ||
450 | 472 | ||
451 | /* Low Energy Advertising Flags */ | 473 | /* Low Energy Advertising Flags */ |
452 | #define LE_AD_LIMITED 0x01 /* Limited Discoverable */ | 474 | #define LE_AD_LIMITED 0x01 /* Limited Discoverable */ |
diff --git a/include/net/bluetooth/hci_core.h b/include/net/bluetooth/hci_core.h index 6afbf5b014a1..b65c53de6a69 100644 --- a/include/net/bluetooth/hci_core.h +++ b/include/net/bluetooth/hci_core.h | |||
@@ -596,7 +596,6 @@ enum { | |||
596 | HCI_CONN_SC_ENABLED, | 596 | HCI_CONN_SC_ENABLED, |
597 | HCI_CONN_AES_CCM, | 597 | HCI_CONN_AES_CCM, |
598 | HCI_CONN_POWER_SAVE, | 598 | HCI_CONN_POWER_SAVE, |
599 | HCI_CONN_REMOTE_OOB, | ||
600 | HCI_CONN_FLUSH_KEY, | 599 | HCI_CONN_FLUSH_KEY, |
601 | HCI_CONN_ENCRYPT, | 600 | HCI_CONN_ENCRYPT, |
602 | HCI_CONN_AUTH, | 601 | HCI_CONN_AUTH, |
@@ -1284,14 +1283,15 @@ void *hci_sent_cmd_data(struct hci_dev *hdev, __u16 opcode); | |||
1284 | /* ----- HCI Sockets ----- */ | 1283 | /* ----- HCI Sockets ----- */ |
1285 | void hci_send_to_sock(struct hci_dev *hdev, struct sk_buff *skb); | 1284 | void hci_send_to_sock(struct hci_dev *hdev, struct sk_buff *skb); |
1286 | void hci_send_to_channel(unsigned short channel, struct sk_buff *skb, | 1285 | void hci_send_to_channel(unsigned short channel, struct sk_buff *skb, |
1287 | struct sock *skip_sk); | 1286 | int flag, struct sock *skip_sk); |
1288 | void hci_send_to_monitor(struct hci_dev *hdev, struct sk_buff *skb); | 1287 | void hci_send_to_monitor(struct hci_dev *hdev, struct sk_buff *skb); |
1289 | 1288 | ||
1290 | void hci_sock_dev_event(struct hci_dev *hdev, int event); | 1289 | void hci_sock_dev_event(struct hci_dev *hdev, int event); |
1291 | 1290 | ||
1292 | #define HCI_MGMT_VAR_LEN (1 << 0) | 1291 | #define HCI_MGMT_VAR_LEN BIT(0) |
1293 | #define HCI_MGMT_NO_HDEV (1 << 1) | 1292 | #define HCI_MGMT_NO_HDEV BIT(1) |
1294 | #define HCI_MGMT_UNCONFIGURED (1 << 2) | 1293 | #define HCI_MGMT_UNTRUSTED BIT(2) |
1294 | #define HCI_MGMT_UNCONFIGURED BIT(3) | ||
1295 | 1295 | ||
1296 | struct hci_mgmt_handler { | 1296 | struct hci_mgmt_handler { |
1297 | int (*func) (struct sock *sk, struct hci_dev *hdev, void *data, | 1297 | int (*func) (struct sock *sk, struct hci_dev *hdev, void *data, |
@@ -1305,6 +1305,7 @@ struct hci_mgmt_chan { | |||
1305 | unsigned short channel; | 1305 | unsigned short channel; |
1306 | size_t handler_count; | 1306 | size_t handler_count; |
1307 | const struct hci_mgmt_handler *handlers; | 1307 | const struct hci_mgmt_handler *handlers; |
1308 | void (*hdev_init) (struct sock *sk, struct hci_dev *hdev); | ||
1308 | }; | 1309 | }; |
1309 | 1310 | ||
1310 | int hci_mgmt_chan_register(struct hci_mgmt_chan *c); | 1311 | int hci_mgmt_chan_register(struct hci_mgmt_chan *c); |
@@ -1329,9 +1330,6 @@ void hci_mgmt_chan_unregister(struct hci_mgmt_chan *c); | |||
1329 | #define DISCOV_BREDR_INQUIRY_LEN 0x08 | 1330 | #define DISCOV_BREDR_INQUIRY_LEN 0x08 |
1330 | #define DISCOV_LE_RESTART_DELAY msecs_to_jiffies(200) /* msec */ | 1331 | #define DISCOV_LE_RESTART_DELAY msecs_to_jiffies(200) /* msec */ |
1331 | 1332 | ||
1332 | int mgmt_control(struct hci_mgmt_chan *chan, struct sock *sk, | ||
1333 | struct msghdr *msg, size_t msglen); | ||
1334 | |||
1335 | int mgmt_new_settings(struct hci_dev *hdev); | 1333 | int mgmt_new_settings(struct hci_dev *hdev); |
1336 | void mgmt_index_added(struct hci_dev *hdev); | 1334 | void mgmt_index_added(struct hci_dev *hdev); |
1337 | void mgmt_index_removed(struct hci_dev *hdev); | 1335 | void mgmt_index_removed(struct hci_dev *hdev); |
diff --git a/include/net/bluetooth/mgmt.h b/include/net/bluetooth/mgmt.h index 5bf6af9cee78..a1a68671bf88 100644 --- a/include/net/bluetooth/mgmt.h +++ b/include/net/bluetooth/mgmt.h | |||
@@ -44,6 +44,7 @@ | |||
44 | #define MGMT_STATUS_INVALID_INDEX 0x11 | 44 | #define MGMT_STATUS_INVALID_INDEX 0x11 |
45 | #define MGMT_STATUS_RFKILLED 0x12 | 45 | #define MGMT_STATUS_RFKILLED 0x12 |
46 | #define MGMT_STATUS_ALREADY_PAIRED 0x13 | 46 | #define MGMT_STATUS_ALREADY_PAIRED 0x13 |
47 | #define MGMT_STATUS_PERMISSION_DENIED 0x14 | ||
47 | 48 | ||
48 | struct mgmt_hdr { | 49 | struct mgmt_hdr { |
49 | __le16 opcode; | 50 | __le16 opcode; |
@@ -505,6 +506,39 @@ struct mgmt_cp_start_service_discovery { | |||
505 | } __packed; | 506 | } __packed; |
506 | #define MGMT_START_SERVICE_DISCOVERY_SIZE 4 | 507 | #define MGMT_START_SERVICE_DISCOVERY_SIZE 4 |
507 | 508 | ||
509 | #define MGMT_OP_READ_LOCAL_OOB_EXT_DATA 0x003B | ||
510 | struct mgmt_cp_read_local_oob_ext_data { | ||
511 | __u8 type; | ||
512 | } __packed; | ||
513 | #define MGMT_READ_LOCAL_OOB_EXT_DATA_SIZE 1 | ||
514 | struct mgmt_rp_read_local_oob_ext_data { | ||
515 | __u8 type; | ||
516 | __le16 eir_len; | ||
517 | __u8 eir[0]; | ||
518 | } __packed; | ||
519 | |||
520 | #define MGMT_OP_READ_EXT_INDEX_LIST 0x003C | ||
521 | #define MGMT_READ_EXT_INDEX_LIST_SIZE 0 | ||
522 | struct mgmt_rp_read_ext_index_list { | ||
523 | __le16 num_controllers; | ||
524 | struct { | ||
525 | __le16 index; | ||
526 | __u8 type; | ||
527 | __u8 bus; | ||
528 | } entry[0]; | ||
529 | } __packed; | ||
530 | |||
531 | #define MGMT_OP_READ_ADV_FEATURES 0x0003D | ||
532 | #define MGMT_READ_ADV_FEATURES_SIZE 0 | ||
533 | struct mgmt_rp_read_adv_features { | ||
534 | __le32 supported_flags; | ||
535 | __u8 max_adv_data_len; | ||
536 | __u8 max_scan_rsp_len; | ||
537 | __u8 max_instances; | ||
538 | __u8 num_instances; | ||
539 | __u8 instance[0]; | ||
540 | } __packed; | ||
541 | |||
508 | #define MGMT_EV_CMD_COMPLETE 0x0001 | 542 | #define MGMT_EV_CMD_COMPLETE 0x0001 |
509 | struct mgmt_ev_cmd_complete { | 543 | struct mgmt_ev_cmd_complete { |
510 | __le16 opcode; | 544 | __le16 opcode; |
@@ -692,3 +726,19 @@ struct mgmt_ev_new_conn_param { | |||
692 | #define MGMT_EV_UNCONF_INDEX_REMOVED 0x001e | 726 | #define MGMT_EV_UNCONF_INDEX_REMOVED 0x001e |
693 | 727 | ||
694 | #define MGMT_EV_NEW_CONFIG_OPTIONS 0x001f | 728 | #define MGMT_EV_NEW_CONFIG_OPTIONS 0x001f |
729 | |||
730 | struct mgmt_ev_ext_index { | ||
731 | __u8 type; | ||
732 | __u8 bus; | ||
733 | } __packed; | ||
734 | |||
735 | #define MGMT_EV_EXT_INDEX_ADDED 0x0020 | ||
736 | |||
737 | #define MGMT_EV_EXT_INDEX_REMOVED 0x0021 | ||
738 | |||
739 | #define MGMT_EV_LOCAL_OOB_DATA_UPDATED 0x0022 | ||
740 | struct mgmt_ev_local_oob_data_updated { | ||
741 | __u8 type; | ||
742 | __le16 eir_len; | ||
743 | __u8 eir[0]; | ||
744 | } __packed; | ||
diff --git a/net/bluetooth/Makefile b/net/bluetooth/Makefile index 5d608799717e..9a8ea232d28f 100644 --- a/net/bluetooth/Makefile +++ b/net/bluetooth/Makefile | |||
@@ -13,7 +13,7 @@ bluetooth_6lowpan-y := 6lowpan.o | |||
13 | 13 | ||
14 | bluetooth-y := af_bluetooth.o hci_core.o hci_conn.o hci_event.o mgmt.o \ | 14 | bluetooth-y := af_bluetooth.o hci_core.o hci_conn.o hci_event.o mgmt.o \ |
15 | hci_sock.o hci_sysfs.o l2cap_core.o l2cap_sock.o smp.o sco.o lib.o \ | 15 | hci_sock.o hci_sysfs.o l2cap_core.o l2cap_sock.o smp.o sco.o lib.o \ |
16 | a2mp.o amp.o ecc.o hci_request.o | 16 | a2mp.o amp.o ecc.o hci_request.o mgmt_util.o |
17 | 17 | ||
18 | bluetooth-$(CONFIG_BT_DEBUGFS) += hci_debugfs.o | 18 | bluetooth-$(CONFIG_BT_DEBUGFS) += hci_debugfs.o |
19 | bluetooth-$(CONFIG_BT_SELFTEST) += selftest.o | 19 | bluetooth-$(CONFIG_BT_SELFTEST) += selftest.o |
diff --git a/net/bluetooth/hci_core.c b/net/bluetooth/hci_core.c index 750d3445f2d2..773f2164d9a1 100644 --- a/net/bluetooth/hci_core.c +++ b/net/bluetooth/hci_core.c | |||
@@ -2902,12 +2902,26 @@ static void le_scan_disable_work_complete(struct hci_dev *hdev, u8 status, | |||
2902 | 2902 | ||
2903 | hci_dev_lock(hdev); | 2903 | hci_dev_lock(hdev); |
2904 | 2904 | ||
2905 | hci_inquiry_cache_flush(hdev); | 2905 | if (test_bit(HCI_QUIRK_SIMULTANEOUS_DISCOVERY, |
2906 | &hdev->quirks)) { | ||
2907 | /* If we were running LE only scan, change discovery | ||
2908 | * state. If we were running both LE and BR/EDR inquiry | ||
2909 | * simultaneously, and BR/EDR inquiry is already | ||
2910 | * finished, stop discovery, otherwise BR/EDR inquiry | ||
2911 | * will stop discovery when finished. | ||
2912 | */ | ||
2913 | if (!test_bit(HCI_INQUIRY, &hdev->flags)) | ||
2914 | hci_discovery_set_state(hdev, | ||
2915 | DISCOVERY_STOPPED); | ||
2916 | } else { | ||
2917 | hci_inquiry_cache_flush(hdev); | ||
2906 | 2918 | ||
2907 | err = hci_req_run(&req, inquiry_complete); | 2919 | err = hci_req_run(&req, inquiry_complete); |
2908 | if (err) { | 2920 | if (err) { |
2909 | BT_ERR("Inquiry request failed: err %d", err); | 2921 | BT_ERR("Inquiry request failed: err %d", err); |
2910 | hci_discovery_set_state(hdev, DISCOVERY_STOPPED); | 2922 | hci_discovery_set_state(hdev, |
2923 | DISCOVERY_STOPPED); | ||
2924 | } | ||
2911 | } | 2925 | } |
2912 | 2926 | ||
2913 | hci_dev_unlock(hdev); | 2927 | hci_dev_unlock(hdev); |
diff --git a/net/bluetooth/hci_debugfs.c b/net/bluetooth/hci_debugfs.c index bc801e9db834..0818fabf346a 100644 --- a/net/bluetooth/hci_debugfs.c +++ b/net/bluetooth/hci_debugfs.c | |||
@@ -166,7 +166,7 @@ static int remote_oob_show(struct seq_file *f, void *ptr) | |||
166 | seq_printf(f, "%pMR (type %u) %u %*phN %*phN %*phN %*phN\n", | 166 | seq_printf(f, "%pMR (type %u) %u %*phN %*phN %*phN %*phN\n", |
167 | &data->bdaddr, data->bdaddr_type, data->present, | 167 | &data->bdaddr, data->bdaddr_type, data->present, |
168 | 16, data->hash192, 16, data->rand192, | 168 | 16, data->hash192, 16, data->rand192, |
169 | 16, data->hash256, 19, data->rand256); | 169 | 16, data->hash256, 16, data->rand256); |
170 | } | 170 | } |
171 | hci_dev_unlock(hdev); | 171 | hci_dev_unlock(hdev); |
172 | 172 | ||
diff --git a/net/bluetooth/hci_event.c b/net/bluetooth/hci_event.c index c7376cd42b1c..62f92a508961 100644 --- a/net/bluetooth/hci_event.c +++ b/net/bluetooth/hci_event.c | |||
@@ -2126,7 +2126,16 @@ static void hci_inquiry_complete_evt(struct hci_dev *hdev, struct sk_buff *skb) | |||
2126 | goto unlock; | 2126 | goto unlock; |
2127 | 2127 | ||
2128 | if (list_empty(&discov->resolve)) { | 2128 | if (list_empty(&discov->resolve)) { |
2129 | hci_discovery_set_state(hdev, DISCOVERY_STOPPED); | 2129 | /* When BR/EDR inquiry is active and no LE scanning is in |
2130 | * progress, then change discovery state to indicate completion. | ||
2131 | * | ||
2132 | * When running LE scanning and BR/EDR inquiry simultaneously | ||
2133 | * and the LE scan already finished, then change the discovery | ||
2134 | * state to indicate completion. | ||
2135 | */ | ||
2136 | if (!hci_dev_test_flag(hdev, HCI_LE_SCAN) || | ||
2137 | !test_bit(HCI_QUIRK_SIMULTANEOUS_DISCOVERY, &hdev->quirks)) | ||
2138 | hci_discovery_set_state(hdev, DISCOVERY_STOPPED); | ||
2130 | goto unlock; | 2139 | goto unlock; |
2131 | } | 2140 | } |
2132 | 2141 | ||
@@ -2135,7 +2144,16 @@ static void hci_inquiry_complete_evt(struct hci_dev *hdev, struct sk_buff *skb) | |||
2135 | e->name_state = NAME_PENDING; | 2144 | e->name_state = NAME_PENDING; |
2136 | hci_discovery_set_state(hdev, DISCOVERY_RESOLVING); | 2145 | hci_discovery_set_state(hdev, DISCOVERY_RESOLVING); |
2137 | } else { | 2146 | } else { |
2138 | hci_discovery_set_state(hdev, DISCOVERY_STOPPED); | 2147 | /* When BR/EDR inquiry is active and no LE scanning is in |
2148 | * progress, then change discovery state to indicate completion. | ||
2149 | * | ||
2150 | * When running LE scanning and BR/EDR inquiry simultaneously | ||
2151 | * and the LE scan already finished, then change the discovery | ||
2152 | * state to indicate completion. | ||
2153 | */ | ||
2154 | if (!hci_dev_test_flag(hdev, HCI_LE_SCAN) || | ||
2155 | !test_bit(HCI_QUIRK_SIMULTANEOUS_DISCOVERY, &hdev->quirks)) | ||
2156 | hci_discovery_set_state(hdev, DISCOVERY_STOPPED); | ||
2139 | } | 2157 | } |
2140 | 2158 | ||
2141 | unlock: | 2159 | unlock: |
@@ -3889,41 +3907,37 @@ static u8 bredr_oob_data_present(struct hci_conn *conn) | |||
3889 | if (!data) | 3907 | if (!data) |
3890 | return 0x00; | 3908 | return 0x00; |
3891 | 3909 | ||
3892 | if (conn->out || test_bit(HCI_CONN_REMOTE_OOB, &conn->flags)) { | 3910 | if (bredr_sc_enabled(hdev)) { |
3893 | if (bredr_sc_enabled(hdev)) { | 3911 | /* When Secure Connections is enabled, then just |
3894 | /* When Secure Connections is enabled, then just | 3912 | * return the present value stored with the OOB |
3895 | * return the present value stored with the OOB | 3913 | * data. The stored value contains the right present |
3896 | * data. The stored value contains the right present | 3914 | * information. However it can only be trusted when |
3897 | * information. However it can only be trusted when | 3915 | * not in Secure Connection Only mode. |
3898 | * not in Secure Connection Only mode. | 3916 | */ |
3899 | */ | 3917 | if (!hci_dev_test_flag(hdev, HCI_SC_ONLY)) |
3900 | if (!hci_dev_test_flag(hdev, HCI_SC_ONLY)) | 3918 | return data->present; |
3901 | return data->present; | ||
3902 | |||
3903 | /* When Secure Connections Only mode is enabled, then | ||
3904 | * the P-256 values are required. If they are not | ||
3905 | * available, then do not declare that OOB data is | ||
3906 | * present. | ||
3907 | */ | ||
3908 | if (!memcmp(data->rand256, ZERO_KEY, 16) || | ||
3909 | !memcmp(data->hash256, ZERO_KEY, 16)) | ||
3910 | return 0x00; | ||
3911 | |||
3912 | return 0x02; | ||
3913 | } | ||
3914 | 3919 | ||
3915 | /* When Secure Connections is not enabled or actually | 3920 | /* When Secure Connections Only mode is enabled, then |
3916 | * not supported by the hardware, then check that if | 3921 | * the P-256 values are required. If they are not |
3917 | * P-192 data values are present. | 3922 | * available, then do not declare that OOB data is |
3923 | * present. | ||
3918 | */ | 3924 | */ |
3919 | if (!memcmp(data->rand192, ZERO_KEY, 16) || | 3925 | if (!memcmp(data->rand256, ZERO_KEY, 16) || |
3920 | !memcmp(data->hash192, ZERO_KEY, 16)) | 3926 | !memcmp(data->hash256, ZERO_KEY, 16)) |
3921 | return 0x00; | 3927 | return 0x00; |
3922 | 3928 | ||
3923 | return 0x01; | 3929 | return 0x02; |
3924 | } | 3930 | } |
3925 | 3931 | ||
3926 | return 0x00; | 3932 | /* When Secure Connections is not enabled or actually |
3933 | * not supported by the hardware, then check that if | ||
3934 | * P-192 data values are present. | ||
3935 | */ | ||
3936 | if (!memcmp(data->rand192, ZERO_KEY, 16) || | ||
3937 | !memcmp(data->hash192, ZERO_KEY, 16)) | ||
3938 | return 0x00; | ||
3939 | |||
3940 | return 0x01; | ||
3927 | } | 3941 | } |
3928 | 3942 | ||
3929 | static void hci_io_capa_request_evt(struct hci_dev *hdev, struct sk_buff *skb) | 3943 | static void hci_io_capa_request_evt(struct hci_dev *hdev, struct sk_buff *skb) |
@@ -4010,8 +4024,6 @@ static void hci_io_capa_reply_evt(struct hci_dev *hdev, struct sk_buff *skb) | |||
4010 | 4024 | ||
4011 | conn->remote_cap = ev->capability; | 4025 | conn->remote_cap = ev->capability; |
4012 | conn->remote_auth = ev->authentication; | 4026 | conn->remote_auth = ev->authentication; |
4013 | if (ev->oob_data) | ||
4014 | set_bit(HCI_CONN_REMOTE_OOB, &conn->flags); | ||
4015 | 4027 | ||
4016 | unlock: | 4028 | unlock: |
4017 | hci_dev_unlock(hdev); | 4029 | hci_dev_unlock(hdev); |
diff --git a/net/bluetooth/hci_sock.c b/net/bluetooth/hci_sock.c index b614543b4fe3..85a44a7dc150 100644 --- a/net/bluetooth/hci_sock.c +++ b/net/bluetooth/hci_sock.c | |||
@@ -30,6 +30,9 @@ | |||
30 | #include <net/bluetooth/bluetooth.h> | 30 | #include <net/bluetooth/bluetooth.h> |
31 | #include <net/bluetooth/hci_core.h> | 31 | #include <net/bluetooth/hci_core.h> |
32 | #include <net/bluetooth/hci_mon.h> | 32 | #include <net/bluetooth/hci_mon.h> |
33 | #include <net/bluetooth/mgmt.h> | ||
34 | |||
35 | #include "mgmt_util.h" | ||
33 | 36 | ||
34 | static LIST_HEAD(mgmt_chan_list); | 37 | static LIST_HEAD(mgmt_chan_list); |
35 | static DEFINE_MUTEX(mgmt_chan_list_lock); | 38 | static DEFINE_MUTEX(mgmt_chan_list_lock); |
@@ -47,8 +50,29 @@ struct hci_pinfo { | |||
47 | struct hci_filter filter; | 50 | struct hci_filter filter; |
48 | __u32 cmsg_mask; | 51 | __u32 cmsg_mask; |
49 | unsigned short channel; | 52 | unsigned short channel; |
53 | unsigned long flags; | ||
50 | }; | 54 | }; |
51 | 55 | ||
56 | void hci_sock_set_flag(struct sock *sk, int nr) | ||
57 | { | ||
58 | set_bit(nr, &hci_pi(sk)->flags); | ||
59 | } | ||
60 | |||
61 | void hci_sock_clear_flag(struct sock *sk, int nr) | ||
62 | { | ||
63 | clear_bit(nr, &hci_pi(sk)->flags); | ||
64 | } | ||
65 | |||
66 | int hci_sock_test_flag(struct sock *sk, int nr) | ||
67 | { | ||
68 | return test_bit(nr, &hci_pi(sk)->flags); | ||
69 | } | ||
70 | |||
71 | unsigned short hci_sock_get_channel(struct sock *sk) | ||
72 | { | ||
73 | return hci_pi(sk)->channel; | ||
74 | } | ||
75 | |||
52 | static inline int hci_test_bit(int nr, const void *addr) | 76 | static inline int hci_test_bit(int nr, const void *addr) |
53 | { | 77 | { |
54 | return *((const __u32 *) addr + (nr >> 5)) & ((__u32) 1 << (nr & 31)); | 78 | return *((const __u32 *) addr + (nr >> 5)) & ((__u32) 1 << (nr & 31)); |
@@ -188,7 +212,7 @@ void hci_send_to_sock(struct hci_dev *hdev, struct sk_buff *skb) | |||
188 | 212 | ||
189 | /* Send frame to sockets with specific channel */ | 213 | /* Send frame to sockets with specific channel */ |
190 | void hci_send_to_channel(unsigned short channel, struct sk_buff *skb, | 214 | void hci_send_to_channel(unsigned short channel, struct sk_buff *skb, |
191 | struct sock *skip_sk) | 215 | int flag, struct sock *skip_sk) |
192 | { | 216 | { |
193 | struct sock *sk; | 217 | struct sock *sk; |
194 | 218 | ||
@@ -199,6 +223,10 @@ void hci_send_to_channel(unsigned short channel, struct sk_buff *skb, | |||
199 | sk_for_each(sk, &hci_sk_list.head) { | 223 | sk_for_each(sk, &hci_sk_list.head) { |
200 | struct sk_buff *nskb; | 224 | struct sk_buff *nskb; |
201 | 225 | ||
226 | /* Ignore socket without the flag set */ | ||
227 | if (!hci_sock_test_flag(sk, flag)) | ||
228 | continue; | ||
229 | |||
202 | /* Skip the original socket */ | 230 | /* Skip the original socket */ |
203 | if (sk == skip_sk) | 231 | if (sk == skip_sk) |
204 | continue; | 232 | continue; |
@@ -266,7 +294,8 @@ void hci_send_to_monitor(struct hci_dev *hdev, struct sk_buff *skb) | |||
266 | hdr->index = cpu_to_le16(hdev->id); | 294 | hdr->index = cpu_to_le16(hdev->id); |
267 | hdr->len = cpu_to_le16(skb->len); | 295 | hdr->len = cpu_to_le16(skb->len); |
268 | 296 | ||
269 | hci_send_to_channel(HCI_CHANNEL_MONITOR, skb_copy, NULL); | 297 | hci_send_to_channel(HCI_CHANNEL_MONITOR, skb_copy, |
298 | HCI_SOCK_TRUSTED, NULL); | ||
270 | kfree_skb(skb_copy); | 299 | kfree_skb(skb_copy); |
271 | } | 300 | } |
272 | 301 | ||
@@ -373,7 +402,8 @@ void hci_sock_dev_event(struct hci_dev *hdev, int event) | |||
373 | 402 | ||
374 | skb = create_monitor_event(hdev, event); | 403 | skb = create_monitor_event(hdev, event); |
375 | if (skb) { | 404 | if (skb) { |
376 | hci_send_to_channel(HCI_CHANNEL_MONITOR, skb, NULL); | 405 | hci_send_to_channel(HCI_CHANNEL_MONITOR, skb, |
406 | HCI_SOCK_TRUSTED, NULL); | ||
377 | kfree_skb(skb); | 407 | kfree_skb(skb); |
378 | } | 408 | } |
379 | } | 409 | } |
@@ -752,6 +782,11 @@ static int hci_sock_bind(struct socket *sock, struct sockaddr *addr, | |||
752 | goto done; | 782 | goto done; |
753 | } | 783 | } |
754 | 784 | ||
785 | /* The monitor interface is restricted to CAP_NET_RAW | ||
786 | * capabilities and with that implicitly trusted. | ||
787 | */ | ||
788 | hci_sock_set_flag(sk, HCI_SOCK_TRUSTED); | ||
789 | |||
755 | send_monitor_replay(sk); | 790 | send_monitor_replay(sk); |
756 | 791 | ||
757 | atomic_inc(&monitor_promisc); | 792 | atomic_inc(&monitor_promisc); |
@@ -768,11 +803,29 @@ static int hci_sock_bind(struct socket *sock, struct sockaddr *addr, | |||
768 | goto done; | 803 | goto done; |
769 | } | 804 | } |
770 | 805 | ||
771 | if (!capable(CAP_NET_ADMIN)) { | 806 | /* Users with CAP_NET_ADMIN capabilities are allowed |
772 | err = -EPERM; | 807 | * access to all management commands and events. For |
773 | goto done; | 808 | * untrusted users the interface is restricted and |
809 | * also only untrusted events are sent. | ||
810 | */ | ||
811 | if (capable(CAP_NET_ADMIN)) | ||
812 | hci_sock_set_flag(sk, HCI_SOCK_TRUSTED); | ||
813 | |||
814 | /* At the moment the index and unconfigured index events | ||
815 | * are enabled unconditionally. Setting them on each | ||
816 | * socket when binding keeps this functionality. They | ||
817 | * however might be cleared later and then sending of these | ||
818 | * events will be disabled, but that is then intentional. | ||
819 | * | ||
820 | * This also enables generic events that are safe to be | ||
821 | * received by untrusted users. Example for such events | ||
822 | * are changes to settings, class of device, name etc. | ||
823 | */ | ||
824 | if (haddr.hci_channel == HCI_CHANNEL_CONTROL) { | ||
825 | hci_sock_set_flag(sk, HCI_MGMT_INDEX_EVENTS); | ||
826 | hci_sock_set_flag(sk, HCI_MGMT_UNCONF_INDEX_EVENTS); | ||
827 | hci_sock_set_flag(sk, HCI_MGMT_GENERIC_EVENTS); | ||
774 | } | 828 | } |
775 | |||
776 | break; | 829 | break; |
777 | } | 830 | } |
778 | 831 | ||
@@ -901,6 +954,117 @@ static int hci_sock_recvmsg(struct socket *sock, struct msghdr *msg, size_t len, | |||
901 | return err ? : copied; | 954 | return err ? : copied; |
902 | } | 955 | } |
903 | 956 | ||
957 | static int hci_mgmt_cmd(struct hci_mgmt_chan *chan, struct sock *sk, | ||
958 | struct msghdr *msg, size_t msglen) | ||
959 | { | ||
960 | void *buf; | ||
961 | u8 *cp; | ||
962 | struct mgmt_hdr *hdr; | ||
963 | u16 opcode, index, len; | ||
964 | struct hci_dev *hdev = NULL; | ||
965 | const struct hci_mgmt_handler *handler; | ||
966 | bool var_len, no_hdev; | ||
967 | int err; | ||
968 | |||
969 | BT_DBG("got %zu bytes", msglen); | ||
970 | |||
971 | if (msglen < sizeof(*hdr)) | ||
972 | return -EINVAL; | ||
973 | |||
974 | buf = kmalloc(msglen, GFP_KERNEL); | ||
975 | if (!buf) | ||
976 | return -ENOMEM; | ||
977 | |||
978 | if (memcpy_from_msg(buf, msg, msglen)) { | ||
979 | err = -EFAULT; | ||
980 | goto done; | ||
981 | } | ||
982 | |||
983 | hdr = buf; | ||
984 | opcode = __le16_to_cpu(hdr->opcode); | ||
985 | index = __le16_to_cpu(hdr->index); | ||
986 | len = __le16_to_cpu(hdr->len); | ||
987 | |||
988 | if (len != msglen - sizeof(*hdr)) { | ||
989 | err = -EINVAL; | ||
990 | goto done; | ||
991 | } | ||
992 | |||
993 | if (opcode >= chan->handler_count || | ||
994 | chan->handlers[opcode].func == NULL) { | ||
995 | BT_DBG("Unknown op %u", opcode); | ||
996 | err = mgmt_cmd_status(sk, index, opcode, | ||
997 | MGMT_STATUS_UNKNOWN_COMMAND); | ||
998 | goto done; | ||
999 | } | ||
1000 | |||
1001 | handler = &chan->handlers[opcode]; | ||
1002 | |||
1003 | if (!hci_sock_test_flag(sk, HCI_SOCK_TRUSTED) && | ||
1004 | !(handler->flags & HCI_MGMT_UNTRUSTED)) { | ||
1005 | err = mgmt_cmd_status(sk, index, opcode, | ||
1006 | MGMT_STATUS_PERMISSION_DENIED); | ||
1007 | goto done; | ||
1008 | } | ||
1009 | |||
1010 | if (index != MGMT_INDEX_NONE) { | ||
1011 | hdev = hci_dev_get(index); | ||
1012 | if (!hdev) { | ||
1013 | err = mgmt_cmd_status(sk, index, opcode, | ||
1014 | MGMT_STATUS_INVALID_INDEX); | ||
1015 | goto done; | ||
1016 | } | ||
1017 | |||
1018 | if (hci_dev_test_flag(hdev, HCI_SETUP) || | ||
1019 | hci_dev_test_flag(hdev, HCI_CONFIG) || | ||
1020 | hci_dev_test_flag(hdev, HCI_USER_CHANNEL)) { | ||
1021 | err = mgmt_cmd_status(sk, index, opcode, | ||
1022 | MGMT_STATUS_INVALID_INDEX); | ||
1023 | goto done; | ||
1024 | } | ||
1025 | |||
1026 | if (hci_dev_test_flag(hdev, HCI_UNCONFIGURED) && | ||
1027 | !(handler->flags & HCI_MGMT_UNCONFIGURED)) { | ||
1028 | err = mgmt_cmd_status(sk, index, opcode, | ||
1029 | MGMT_STATUS_INVALID_INDEX); | ||
1030 | goto done; | ||
1031 | } | ||
1032 | } | ||
1033 | |||
1034 | no_hdev = (handler->flags & HCI_MGMT_NO_HDEV); | ||
1035 | if (no_hdev != !hdev) { | ||
1036 | err = mgmt_cmd_status(sk, index, opcode, | ||
1037 | MGMT_STATUS_INVALID_INDEX); | ||
1038 | goto done; | ||
1039 | } | ||
1040 | |||
1041 | var_len = (handler->flags & HCI_MGMT_VAR_LEN); | ||
1042 | if ((var_len && len < handler->data_len) || | ||
1043 | (!var_len && len != handler->data_len)) { | ||
1044 | err = mgmt_cmd_status(sk, index, opcode, | ||
1045 | MGMT_STATUS_INVALID_PARAMS); | ||
1046 | goto done; | ||
1047 | } | ||
1048 | |||
1049 | if (hdev && chan->hdev_init) | ||
1050 | chan->hdev_init(sk, hdev); | ||
1051 | |||
1052 | cp = buf + sizeof(*hdr); | ||
1053 | |||
1054 | err = handler->func(sk, hdev, cp, len); | ||
1055 | if (err < 0) | ||
1056 | goto done; | ||
1057 | |||
1058 | err = msglen; | ||
1059 | |||
1060 | done: | ||
1061 | if (hdev) | ||
1062 | hci_dev_put(hdev); | ||
1063 | |||
1064 | kfree(buf); | ||
1065 | return err; | ||
1066 | } | ||
1067 | |||
904 | static int hci_sock_sendmsg(struct socket *sock, struct msghdr *msg, | 1068 | static int hci_sock_sendmsg(struct socket *sock, struct msghdr *msg, |
905 | size_t len) | 1069 | size_t len) |
906 | { | 1070 | { |
@@ -934,7 +1098,7 @@ static int hci_sock_sendmsg(struct socket *sock, struct msghdr *msg, | |||
934 | mutex_lock(&mgmt_chan_list_lock); | 1098 | mutex_lock(&mgmt_chan_list_lock); |
935 | chan = __hci_mgmt_chan_find(hci_pi(sk)->channel); | 1099 | chan = __hci_mgmt_chan_find(hci_pi(sk)->channel); |
936 | if (chan) | 1100 | if (chan) |
937 | err = mgmt_control(chan, sk, msg, len); | 1101 | err = hci_mgmt_cmd(chan, sk, msg, len); |
938 | else | 1102 | else |
939 | err = -EINVAL; | 1103 | err = -EINVAL; |
940 | 1104 | ||
diff --git a/net/bluetooth/mgmt.c b/net/bluetooth/mgmt.c index c58908652519..f3a957905193 100644 --- a/net/bluetooth/mgmt.c +++ b/net/bluetooth/mgmt.c | |||
@@ -35,6 +35,7 @@ | |||
35 | 35 | ||
36 | #include "hci_request.h" | 36 | #include "hci_request.h" |
37 | #include "smp.h" | 37 | #include "smp.h" |
38 | #include "mgmt_util.h" | ||
38 | 39 | ||
39 | #define MGMT_VERSION 1 | 40 | #define MGMT_VERSION 1 |
40 | #define MGMT_REVISION 9 | 41 | #define MGMT_REVISION 9 |
@@ -96,6 +97,9 @@ static const u16 mgmt_commands[] = { | |||
96 | MGMT_OP_SET_EXTERNAL_CONFIG, | 97 | MGMT_OP_SET_EXTERNAL_CONFIG, |
97 | MGMT_OP_SET_PUBLIC_ADDRESS, | 98 | MGMT_OP_SET_PUBLIC_ADDRESS, |
98 | MGMT_OP_START_SERVICE_DISCOVERY, | 99 | MGMT_OP_START_SERVICE_DISCOVERY, |
100 | MGMT_OP_READ_LOCAL_OOB_EXT_DATA, | ||
101 | MGMT_OP_READ_EXT_INDEX_LIST, | ||
102 | MGMT_OP_READ_ADV_FEATURES, | ||
99 | }; | 103 | }; |
100 | 104 | ||
101 | static const u16 mgmt_events[] = { | 105 | static const u16 mgmt_events[] = { |
@@ -128,6 +132,9 @@ static const u16 mgmt_events[] = { | |||
128 | MGMT_EV_UNCONF_INDEX_ADDED, | 132 | MGMT_EV_UNCONF_INDEX_ADDED, |
129 | MGMT_EV_UNCONF_INDEX_REMOVED, | 133 | MGMT_EV_UNCONF_INDEX_REMOVED, |
130 | MGMT_EV_NEW_CONFIG_OPTIONS, | 134 | MGMT_EV_NEW_CONFIG_OPTIONS, |
135 | MGMT_EV_EXT_INDEX_ADDED, | ||
136 | MGMT_EV_EXT_INDEX_REMOVED, | ||
137 | MGMT_EV_LOCAL_OOB_DATA_UPDATED, | ||
131 | }; | 138 | }; |
132 | 139 | ||
133 | #define CACHE_TIMEOUT msecs_to_jiffies(2 * 1000) | 140 | #define CACHE_TIMEOUT msecs_to_jiffies(2 * 1000) |
@@ -135,17 +142,6 @@ static const u16 mgmt_events[] = { | |||
135 | #define ZERO_KEY "\x00\x00\x00\x00\x00\x00\x00\x00" \ | 142 | #define ZERO_KEY "\x00\x00\x00\x00\x00\x00\x00\x00" \ |
136 | "\x00\x00\x00\x00\x00\x00\x00\x00" | 143 | "\x00\x00\x00\x00\x00\x00\x00\x00" |
137 | 144 | ||
138 | struct mgmt_pending_cmd { | ||
139 | struct list_head list; | ||
140 | u16 opcode; | ||
141 | int index; | ||
142 | void *param; | ||
143 | size_t param_len; | ||
144 | struct sock *sk; | ||
145 | void *user_data; | ||
146 | int (*cmd_complete)(struct mgmt_pending_cmd *cmd, u8 status); | ||
147 | }; | ||
148 | |||
149 | /* HCI to MGMT error code conversion table */ | 145 | /* HCI to MGMT error code conversion table */ |
150 | static u8 mgmt_status_table[] = { | 146 | static u8 mgmt_status_table[] = { |
151 | MGMT_STATUS_SUCCESS, | 147 | MGMT_STATUS_SUCCESS, |
@@ -219,106 +215,32 @@ static u8 mgmt_status(u8 hci_status) | |||
219 | return MGMT_STATUS_FAILED; | 215 | return MGMT_STATUS_FAILED; |
220 | } | 216 | } |
221 | 217 | ||
222 | static int mgmt_send_event(u16 event, struct hci_dev *hdev, | 218 | static int mgmt_index_event(u16 event, struct hci_dev *hdev, void *data, |
223 | unsigned short channel, void *data, u16 data_len, | 219 | u16 len, int flag) |
224 | struct sock *skip_sk) | ||
225 | { | 220 | { |
226 | struct sk_buff *skb; | 221 | return mgmt_send_event(event, hdev, HCI_CHANNEL_CONTROL, data, len, |
227 | struct mgmt_hdr *hdr; | 222 | flag, NULL); |
228 | |||
229 | skb = alloc_skb(sizeof(*hdr) + data_len, GFP_KERNEL); | ||
230 | if (!skb) | ||
231 | return -ENOMEM; | ||
232 | |||
233 | hdr = (void *) skb_put(skb, sizeof(*hdr)); | ||
234 | hdr->opcode = cpu_to_le16(event); | ||
235 | if (hdev) | ||
236 | hdr->index = cpu_to_le16(hdev->id); | ||
237 | else | ||
238 | hdr->index = cpu_to_le16(MGMT_INDEX_NONE); | ||
239 | hdr->len = cpu_to_le16(data_len); | ||
240 | |||
241 | if (data) | ||
242 | memcpy(skb_put(skb, data_len), data, data_len); | ||
243 | |||
244 | /* Time stamp */ | ||
245 | __net_timestamp(skb); | ||
246 | |||
247 | hci_send_to_channel(channel, skb, skip_sk); | ||
248 | kfree_skb(skb); | ||
249 | |||
250 | return 0; | ||
251 | } | 223 | } |
252 | 224 | ||
253 | static int mgmt_event(u16 event, struct hci_dev *hdev, void *data, u16 len, | 225 | static int mgmt_limited_event(u16 event, struct hci_dev *hdev, void *data, |
254 | struct sock *skip_sk) | 226 | u16 len, int flag, struct sock *skip_sk) |
255 | { | 227 | { |
256 | return mgmt_send_event(event, hdev, HCI_CHANNEL_CONTROL, data, len, | 228 | return mgmt_send_event(event, hdev, HCI_CHANNEL_CONTROL, data, len, |
257 | skip_sk); | 229 | flag, skip_sk); |
258 | } | 230 | } |
259 | 231 | ||
260 | static int mgmt_cmd_status(struct sock *sk, u16 index, u16 cmd, u8 status) | 232 | static int mgmt_generic_event(u16 event, struct hci_dev *hdev, void *data, |
233 | u16 len, struct sock *skip_sk) | ||
261 | { | 234 | { |
262 | struct sk_buff *skb; | 235 | return mgmt_send_event(event, hdev, HCI_CHANNEL_CONTROL, data, len, |
263 | struct mgmt_hdr *hdr; | 236 | HCI_MGMT_GENERIC_EVENTS, skip_sk); |
264 | struct mgmt_ev_cmd_status *ev; | ||
265 | int err; | ||
266 | |||
267 | BT_DBG("sock %p, index %u, cmd %u, status %u", sk, index, cmd, status); | ||
268 | |||
269 | skb = alloc_skb(sizeof(*hdr) + sizeof(*ev), GFP_KERNEL); | ||
270 | if (!skb) | ||
271 | return -ENOMEM; | ||
272 | |||
273 | hdr = (void *) skb_put(skb, sizeof(*hdr)); | ||
274 | |||
275 | hdr->opcode = cpu_to_le16(MGMT_EV_CMD_STATUS); | ||
276 | hdr->index = cpu_to_le16(index); | ||
277 | hdr->len = cpu_to_le16(sizeof(*ev)); | ||
278 | |||
279 | ev = (void *) skb_put(skb, sizeof(*ev)); | ||
280 | ev->status = status; | ||
281 | ev->opcode = cpu_to_le16(cmd); | ||
282 | |||
283 | err = sock_queue_rcv_skb(sk, skb); | ||
284 | if (err < 0) | ||
285 | kfree_skb(skb); | ||
286 | |||
287 | return err; | ||
288 | } | 237 | } |
289 | 238 | ||
290 | static int mgmt_cmd_complete(struct sock *sk, u16 index, u16 cmd, u8 status, | 239 | static int mgmt_event(u16 event, struct hci_dev *hdev, void *data, u16 len, |
291 | void *rp, size_t rp_len) | 240 | struct sock *skip_sk) |
292 | { | 241 | { |
293 | struct sk_buff *skb; | 242 | return mgmt_send_event(event, hdev, HCI_CHANNEL_CONTROL, data, len, |
294 | struct mgmt_hdr *hdr; | 243 | HCI_SOCK_TRUSTED, skip_sk); |
295 | struct mgmt_ev_cmd_complete *ev; | ||
296 | int err; | ||
297 | |||
298 | BT_DBG("sock %p", sk); | ||
299 | |||
300 | skb = alloc_skb(sizeof(*hdr) + sizeof(*ev) + rp_len, GFP_KERNEL); | ||
301 | if (!skb) | ||
302 | return -ENOMEM; | ||
303 | |||
304 | hdr = (void *) skb_put(skb, sizeof(*hdr)); | ||
305 | |||
306 | hdr->opcode = cpu_to_le16(MGMT_EV_CMD_COMPLETE); | ||
307 | hdr->index = cpu_to_le16(index); | ||
308 | hdr->len = cpu_to_le16(sizeof(*ev) + rp_len); | ||
309 | |||
310 | ev = (void *) skb_put(skb, sizeof(*ev) + rp_len); | ||
311 | ev->opcode = cpu_to_le16(cmd); | ||
312 | ev->status = status; | ||
313 | |||
314 | if (rp) | ||
315 | memcpy(ev->data, rp, rp_len); | ||
316 | |||
317 | err = sock_queue_rcv_skb(sk, skb); | ||
318 | if (err < 0) | ||
319 | kfree_skb(skb); | ||
320 | |||
321 | return err; | ||
322 | } | 244 | } |
323 | 245 | ||
324 | static int read_version(struct sock *sk, struct hci_dev *hdev, void *data, | 246 | static int read_version(struct sock *sk, struct hci_dev *hdev, void *data, |
@@ -489,6 +411,82 @@ static int read_unconf_index_list(struct sock *sk, struct hci_dev *hdev, | |||
489 | return err; | 411 | return err; |
490 | } | 412 | } |
491 | 413 | ||
414 | static int read_ext_index_list(struct sock *sk, struct hci_dev *hdev, | ||
415 | void *data, u16 data_len) | ||
416 | { | ||
417 | struct mgmt_rp_read_ext_index_list *rp; | ||
418 | struct hci_dev *d; | ||
419 | size_t rp_len; | ||
420 | u16 count; | ||
421 | int err; | ||
422 | |||
423 | BT_DBG("sock %p", sk); | ||
424 | |||
425 | read_lock(&hci_dev_list_lock); | ||
426 | |||
427 | count = 0; | ||
428 | list_for_each_entry(d, &hci_dev_list, list) { | ||
429 | if (d->dev_type == HCI_BREDR || d->dev_type == HCI_AMP) | ||
430 | count++; | ||
431 | } | ||
432 | |||
433 | rp_len = sizeof(*rp) + (sizeof(rp->entry[0]) * count); | ||
434 | rp = kmalloc(rp_len, GFP_ATOMIC); | ||
435 | if (!rp) { | ||
436 | read_unlock(&hci_dev_list_lock); | ||
437 | return -ENOMEM; | ||
438 | } | ||
439 | |||
440 | count = 0; | ||
441 | list_for_each_entry(d, &hci_dev_list, list) { | ||
442 | if (hci_dev_test_flag(d, HCI_SETUP) || | ||
443 | hci_dev_test_flag(d, HCI_CONFIG) || | ||
444 | hci_dev_test_flag(d, HCI_USER_CHANNEL)) | ||
445 | continue; | ||
446 | |||
447 | /* Devices marked as raw-only are neither configured | ||
448 | * nor unconfigured controllers. | ||
449 | */ | ||
450 | if (test_bit(HCI_QUIRK_RAW_DEVICE, &d->quirks)) | ||
451 | continue; | ||
452 | |||
453 | if (d->dev_type == HCI_BREDR) { | ||
454 | if (hci_dev_test_flag(d, HCI_UNCONFIGURED)) | ||
455 | rp->entry[count].type = 0x01; | ||
456 | else | ||
457 | rp->entry[count].type = 0x00; | ||
458 | } else if (d->dev_type == HCI_AMP) { | ||
459 | rp->entry[count].type = 0x02; | ||
460 | } else { | ||
461 | continue; | ||
462 | } | ||
463 | |||
464 | rp->entry[count].bus = d->bus; | ||
465 | rp->entry[count++].index = cpu_to_le16(d->id); | ||
466 | BT_DBG("Added hci%u", d->id); | ||
467 | } | ||
468 | |||
469 | rp->num_controllers = cpu_to_le16(count); | ||
470 | rp_len = sizeof(*rp) + (sizeof(rp->entry[0]) * count); | ||
471 | |||
472 | read_unlock(&hci_dev_list_lock); | ||
473 | |||
474 | /* If this command is called at least once, then all the | ||
475 | * default index and unconfigured index events are disabled | ||
476 | * and from now on only extended index events are used. | ||
477 | */ | ||
478 | hci_sock_set_flag(sk, HCI_MGMT_EXT_INDEX_EVENTS); | ||
479 | hci_sock_clear_flag(sk, HCI_MGMT_INDEX_EVENTS); | ||
480 | hci_sock_clear_flag(sk, HCI_MGMT_UNCONF_INDEX_EVENTS); | ||
481 | |||
482 | err = mgmt_cmd_complete(sk, MGMT_INDEX_NONE, | ||
483 | MGMT_OP_READ_EXT_INDEX_LIST, 0, rp, rp_len); | ||
484 | |||
485 | kfree(rp); | ||
486 | |||
487 | return err; | ||
488 | } | ||
489 | |||
492 | static bool is_configured(struct hci_dev *hdev) | 490 | static bool is_configured(struct hci_dev *hdev) |
493 | { | 491 | { |
494 | if (test_bit(HCI_QUIRK_EXTERNAL_CONFIG, &hdev->quirks) && | 492 | if (test_bit(HCI_QUIRK_EXTERNAL_CONFIG, &hdev->quirks) && |
@@ -521,8 +519,8 @@ static int new_options(struct hci_dev *hdev, struct sock *skip) | |||
521 | { | 519 | { |
522 | __le32 options = get_missing_options(hdev); | 520 | __le32 options = get_missing_options(hdev); |
523 | 521 | ||
524 | return mgmt_event(MGMT_EV_NEW_CONFIG_OPTIONS, hdev, &options, | 522 | return mgmt_generic_event(MGMT_EV_NEW_CONFIG_OPTIONS, hdev, &options, |
525 | sizeof(options), skip); | 523 | sizeof(options), skip); |
526 | } | 524 | } |
527 | 525 | ||
528 | static int send_options_rsp(struct sock *sk, u16 opcode, struct hci_dev *hdev) | 526 | static int send_options_rsp(struct sock *sk, u16 opcode, struct hci_dev *hdev) |
@@ -779,33 +777,16 @@ static u8 *create_uuid128_list(struct hci_dev *hdev, u8 *data, ptrdiff_t len) | |||
779 | return ptr; | 777 | return ptr; |
780 | } | 778 | } |
781 | 779 | ||
782 | static struct mgmt_pending_cmd *mgmt_pending_find(u16 opcode, | 780 | static struct mgmt_pending_cmd *pending_find(u16 opcode, struct hci_dev *hdev) |
783 | struct hci_dev *hdev) | ||
784 | { | 781 | { |
785 | struct mgmt_pending_cmd *cmd; | 782 | return mgmt_pending_find(HCI_CHANNEL_CONTROL, opcode, hdev); |
786 | |||
787 | list_for_each_entry(cmd, &hdev->mgmt_pending, list) { | ||
788 | if (cmd->opcode == opcode) | ||
789 | return cmd; | ||
790 | } | ||
791 | |||
792 | return NULL; | ||
793 | } | 783 | } |
794 | 784 | ||
795 | static struct mgmt_pending_cmd *mgmt_pending_find_data(u16 opcode, | 785 | static struct mgmt_pending_cmd *pending_find_data(u16 opcode, |
796 | struct hci_dev *hdev, | 786 | struct hci_dev *hdev, |
797 | const void *data) | 787 | const void *data) |
798 | { | 788 | { |
799 | struct mgmt_pending_cmd *cmd; | 789 | return mgmt_pending_find_data(HCI_CHANNEL_CONTROL, opcode, hdev, data); |
800 | |||
801 | list_for_each_entry(cmd, &hdev->mgmt_pending, list) { | ||
802 | if (cmd->user_data != data) | ||
803 | continue; | ||
804 | if (cmd->opcode == opcode) | ||
805 | return cmd; | ||
806 | } | ||
807 | |||
808 | return NULL; | ||
809 | } | 790 | } |
810 | 791 | ||
811 | static u8 create_scan_rsp_data(struct hci_dev *hdev, u8 *ptr) | 792 | static u8 create_scan_rsp_data(struct hci_dev *hdev, u8 *ptr) |
@@ -866,7 +847,7 @@ static u8 get_adv_discov_flags(struct hci_dev *hdev) | |||
866 | /* If there's a pending mgmt command the flags will not yet have | 847 | /* If there's a pending mgmt command the flags will not yet have |
867 | * their final values, so check for this first. | 848 | * their final values, so check for this first. |
868 | */ | 849 | */ |
869 | cmd = mgmt_pending_find(MGMT_OP_SET_DISCOVERABLE, hdev); | 850 | cmd = pending_find(MGMT_OP_SET_DISCOVERABLE, hdev); |
870 | if (cmd) { | 851 | if (cmd) { |
871 | struct mgmt_mode *cp = cmd->param; | 852 | struct mgmt_mode *cp = cmd->param; |
872 | if (cp->val == 0x01) | 853 | if (cp->val == 0x01) |
@@ -1074,7 +1055,7 @@ static bool get_connectable(struct hci_dev *hdev) | |||
1074 | /* If there's a pending mgmt command the flag will not yet have | 1055 | /* If there's a pending mgmt command the flag will not yet have |
1075 | * it's final value, so check for this first. | 1056 | * it's final value, so check for this first. |
1076 | */ | 1057 | */ |
1077 | cmd = mgmt_pending_find(MGMT_OP_SET_CONNECTABLE, hdev); | 1058 | cmd = pending_find(MGMT_OP_SET_CONNECTABLE, hdev); |
1078 | if (cmd) { | 1059 | if (cmd) { |
1079 | struct mgmt_mode *cp = cmd->param; | 1060 | struct mgmt_mode *cp = cmd->param; |
1080 | return cp->val; | 1061 | return cp->val; |
@@ -1222,63 +1203,6 @@ static int read_controller_info(struct sock *sk, struct hci_dev *hdev, | |||
1222 | sizeof(rp)); | 1203 | sizeof(rp)); |
1223 | } | 1204 | } |
1224 | 1205 | ||
1225 | static void mgmt_pending_free(struct mgmt_pending_cmd *cmd) | ||
1226 | { | ||
1227 | sock_put(cmd->sk); | ||
1228 | kfree(cmd->param); | ||
1229 | kfree(cmd); | ||
1230 | } | ||
1231 | |||
1232 | static struct mgmt_pending_cmd *mgmt_pending_add(struct sock *sk, u16 opcode, | ||
1233 | struct hci_dev *hdev, | ||
1234 | void *data, u16 len) | ||
1235 | { | ||
1236 | struct mgmt_pending_cmd *cmd; | ||
1237 | |||
1238 | cmd = kzalloc(sizeof(*cmd), GFP_KERNEL); | ||
1239 | if (!cmd) | ||
1240 | return NULL; | ||
1241 | |||
1242 | cmd->opcode = opcode; | ||
1243 | cmd->index = hdev->id; | ||
1244 | |||
1245 | cmd->param = kmemdup(data, len, GFP_KERNEL); | ||
1246 | if (!cmd->param) { | ||
1247 | kfree(cmd); | ||
1248 | return NULL; | ||
1249 | } | ||
1250 | |||
1251 | cmd->param_len = len; | ||
1252 | |||
1253 | cmd->sk = sk; | ||
1254 | sock_hold(sk); | ||
1255 | |||
1256 | list_add(&cmd->list, &hdev->mgmt_pending); | ||
1257 | |||
1258 | return cmd; | ||
1259 | } | ||
1260 | |||
1261 | static void mgmt_pending_foreach(u16 opcode, struct hci_dev *hdev, | ||
1262 | void (*cb)(struct mgmt_pending_cmd *cmd, | ||
1263 | void *data), | ||
1264 | void *data) | ||
1265 | { | ||
1266 | struct mgmt_pending_cmd *cmd, *tmp; | ||
1267 | |||
1268 | list_for_each_entry_safe(cmd, tmp, &hdev->mgmt_pending, list) { | ||
1269 | if (opcode > 0 && cmd->opcode != opcode) | ||
1270 | continue; | ||
1271 | |||
1272 | cb(cmd, data); | ||
1273 | } | ||
1274 | } | ||
1275 | |||
1276 | static void mgmt_pending_remove(struct mgmt_pending_cmd *cmd) | ||
1277 | { | ||
1278 | list_del(&cmd->list); | ||
1279 | mgmt_pending_free(cmd); | ||
1280 | } | ||
1281 | |||
1282 | static int send_settings_rsp(struct sock *sk, u16 opcode, struct hci_dev *hdev) | 1206 | static int send_settings_rsp(struct sock *sk, u16 opcode, struct hci_dev *hdev) |
1283 | { | 1207 | { |
1284 | __le32 settings = cpu_to_le32(get_current_settings(hdev)); | 1208 | __le32 settings = cpu_to_le32(get_current_settings(hdev)); |
@@ -1305,9 +1229,10 @@ static bool hci_stop_discovery(struct hci_request *req) | |||
1305 | 1229 | ||
1306 | switch (hdev->discovery.state) { | 1230 | switch (hdev->discovery.state) { |
1307 | case DISCOVERY_FINDING: | 1231 | case DISCOVERY_FINDING: |
1308 | if (test_bit(HCI_INQUIRY, &hdev->flags)) { | 1232 | if (test_bit(HCI_INQUIRY, &hdev->flags)) |
1309 | hci_req_add(req, HCI_OP_INQUIRY_CANCEL, 0, NULL); | 1233 | hci_req_add(req, HCI_OP_INQUIRY_CANCEL, 0, NULL); |
1310 | } else { | 1234 | |
1235 | if (hci_dev_test_flag(hdev, HCI_LE_SCAN)) { | ||
1311 | cancel_delayed_work(&hdev->le_scan_disable); | 1236 | cancel_delayed_work(&hdev->le_scan_disable); |
1312 | hci_req_add_le_scan_disable(req); | 1237 | hci_req_add_le_scan_disable(req); |
1313 | } | 1238 | } |
@@ -1413,7 +1338,7 @@ static int set_powered(struct sock *sk, struct hci_dev *hdev, void *data, | |||
1413 | 1338 | ||
1414 | hci_dev_lock(hdev); | 1339 | hci_dev_lock(hdev); |
1415 | 1340 | ||
1416 | if (mgmt_pending_find(MGMT_OP_SET_POWERED, hdev)) { | 1341 | if (pending_find(MGMT_OP_SET_POWERED, hdev)) { |
1417 | err = mgmt_cmd_status(sk, hdev->id, MGMT_OP_SET_POWERED, | 1342 | err = mgmt_cmd_status(sk, hdev->id, MGMT_OP_SET_POWERED, |
1418 | MGMT_STATUS_BUSY); | 1343 | MGMT_STATUS_BUSY); |
1419 | goto failed; | 1344 | goto failed; |
@@ -1466,11 +1391,10 @@ failed: | |||
1466 | 1391 | ||
1467 | static int new_settings(struct hci_dev *hdev, struct sock *skip) | 1392 | static int new_settings(struct hci_dev *hdev, struct sock *skip) |
1468 | { | 1393 | { |
1469 | __le32 ev; | 1394 | __le32 ev = cpu_to_le32(get_current_settings(hdev)); |
1470 | |||
1471 | ev = cpu_to_le32(get_current_settings(hdev)); | ||
1472 | 1395 | ||
1473 | return mgmt_event(MGMT_EV_NEW_SETTINGS, hdev, &ev, sizeof(ev), skip); | 1396 | return mgmt_generic_event(MGMT_EV_NEW_SETTINGS, hdev, &ev, |
1397 | sizeof(ev), skip); | ||
1474 | } | 1398 | } |
1475 | 1399 | ||
1476 | int mgmt_new_settings(struct hci_dev *hdev) | 1400 | int mgmt_new_settings(struct hci_dev *hdev) |
@@ -1566,7 +1490,7 @@ static void set_discoverable_complete(struct hci_dev *hdev, u8 status, | |||
1566 | 1490 | ||
1567 | hci_dev_lock(hdev); | 1491 | hci_dev_lock(hdev); |
1568 | 1492 | ||
1569 | cmd = mgmt_pending_find(MGMT_OP_SET_DISCOVERABLE, hdev); | 1493 | cmd = pending_find(MGMT_OP_SET_DISCOVERABLE, hdev); |
1570 | if (!cmd) | 1494 | if (!cmd) |
1571 | goto unlock; | 1495 | goto unlock; |
1572 | 1496 | ||
@@ -1651,8 +1575,8 @@ static int set_discoverable(struct sock *sk, struct hci_dev *hdev, void *data, | |||
1651 | goto failed; | 1575 | goto failed; |
1652 | } | 1576 | } |
1653 | 1577 | ||
1654 | if (mgmt_pending_find(MGMT_OP_SET_DISCOVERABLE, hdev) || | 1578 | if (pending_find(MGMT_OP_SET_DISCOVERABLE, hdev) || |
1655 | mgmt_pending_find(MGMT_OP_SET_CONNECTABLE, hdev)) { | 1579 | pending_find(MGMT_OP_SET_CONNECTABLE, hdev)) { |
1656 | err = mgmt_cmd_status(sk, hdev->id, MGMT_OP_SET_DISCOVERABLE, | 1580 | err = mgmt_cmd_status(sk, hdev->id, MGMT_OP_SET_DISCOVERABLE, |
1657 | MGMT_STATUS_BUSY); | 1581 | MGMT_STATUS_BUSY); |
1658 | goto failed; | 1582 | goto failed; |
@@ -1823,7 +1747,7 @@ static void set_connectable_complete(struct hci_dev *hdev, u8 status, | |||
1823 | 1747 | ||
1824 | hci_dev_lock(hdev); | 1748 | hci_dev_lock(hdev); |
1825 | 1749 | ||
1826 | cmd = mgmt_pending_find(MGMT_OP_SET_CONNECTABLE, hdev); | 1750 | cmd = pending_find(MGMT_OP_SET_CONNECTABLE, hdev); |
1827 | if (!cmd) | 1751 | if (!cmd) |
1828 | goto unlock; | 1752 | goto unlock; |
1829 | 1753 | ||
@@ -1918,8 +1842,8 @@ static int set_connectable(struct sock *sk, struct hci_dev *hdev, void *data, | |||
1918 | goto failed; | 1842 | goto failed; |
1919 | } | 1843 | } |
1920 | 1844 | ||
1921 | if (mgmt_pending_find(MGMT_OP_SET_DISCOVERABLE, hdev) || | 1845 | if (pending_find(MGMT_OP_SET_DISCOVERABLE, hdev) || |
1922 | mgmt_pending_find(MGMT_OP_SET_CONNECTABLE, hdev)) { | 1846 | pending_find(MGMT_OP_SET_CONNECTABLE, hdev)) { |
1923 | err = mgmt_cmd_status(sk, hdev->id, MGMT_OP_SET_CONNECTABLE, | 1847 | err = mgmt_cmd_status(sk, hdev->id, MGMT_OP_SET_CONNECTABLE, |
1924 | MGMT_STATUS_BUSY); | 1848 | MGMT_STATUS_BUSY); |
1925 | goto failed; | 1849 | goto failed; |
@@ -2058,7 +1982,7 @@ static int set_link_security(struct sock *sk, struct hci_dev *hdev, void *data, | |||
2058 | goto failed; | 1982 | goto failed; |
2059 | } | 1983 | } |
2060 | 1984 | ||
2061 | if (mgmt_pending_find(MGMT_OP_SET_LINK_SECURITY, hdev)) { | 1985 | if (pending_find(MGMT_OP_SET_LINK_SECURITY, hdev)) { |
2062 | err = mgmt_cmd_status(sk, hdev->id, MGMT_OP_SET_LINK_SECURITY, | 1986 | err = mgmt_cmd_status(sk, hdev->id, MGMT_OP_SET_LINK_SECURITY, |
2063 | MGMT_STATUS_BUSY); | 1987 | MGMT_STATUS_BUSY); |
2064 | goto failed; | 1988 | goto failed; |
@@ -2137,7 +2061,7 @@ static int set_ssp(struct sock *sk, struct hci_dev *hdev, void *data, u16 len) | |||
2137 | goto failed; | 2061 | goto failed; |
2138 | } | 2062 | } |
2139 | 2063 | ||
2140 | if (mgmt_pending_find(MGMT_OP_SET_SSP, hdev)) { | 2064 | if (pending_find(MGMT_OP_SET_SSP, hdev)) { |
2141 | err = mgmt_cmd_status(sk, hdev->id, MGMT_OP_SET_SSP, | 2065 | err = mgmt_cmd_status(sk, hdev->id, MGMT_OP_SET_SSP, |
2142 | MGMT_STATUS_BUSY); | 2066 | MGMT_STATUS_BUSY); |
2143 | goto failed; | 2067 | goto failed; |
@@ -2196,7 +2120,7 @@ static int set_hs(struct sock *sk, struct hci_dev *hdev, void *data, u16 len) | |||
2196 | 2120 | ||
2197 | hci_dev_lock(hdev); | 2121 | hci_dev_lock(hdev); |
2198 | 2122 | ||
2199 | if (mgmt_pending_find(MGMT_OP_SET_SSP, hdev)) { | 2123 | if (pending_find(MGMT_OP_SET_SSP, hdev)) { |
2200 | err = mgmt_cmd_status(sk, hdev->id, MGMT_OP_SET_HS, | 2124 | err = mgmt_cmd_status(sk, hdev->id, MGMT_OP_SET_HS, |
2201 | MGMT_STATUS_BUSY); | 2125 | MGMT_STATUS_BUSY); |
2202 | goto unlock; | 2126 | goto unlock; |
@@ -2318,8 +2242,8 @@ static int set_le(struct sock *sk, struct hci_dev *hdev, void *data, u16 len) | |||
2318 | goto unlock; | 2242 | goto unlock; |
2319 | } | 2243 | } |
2320 | 2244 | ||
2321 | if (mgmt_pending_find(MGMT_OP_SET_LE, hdev) || | 2245 | if (pending_find(MGMT_OP_SET_LE, hdev) || |
2322 | mgmt_pending_find(MGMT_OP_SET_ADVERTISING, hdev)) { | 2246 | pending_find(MGMT_OP_SET_ADVERTISING, hdev)) { |
2323 | err = mgmt_cmd_status(sk, hdev->id, MGMT_OP_SET_LE, | 2247 | err = mgmt_cmd_status(sk, hdev->id, MGMT_OP_SET_LE, |
2324 | MGMT_STATUS_BUSY); | 2248 | MGMT_STATUS_BUSY); |
2325 | goto unlock; | 2249 | goto unlock; |
@@ -2403,7 +2327,7 @@ static void mgmt_class_complete(struct hci_dev *hdev, u16 mgmt_op, u8 status) | |||
2403 | 2327 | ||
2404 | hci_dev_lock(hdev); | 2328 | hci_dev_lock(hdev); |
2405 | 2329 | ||
2406 | cmd = mgmt_pending_find(mgmt_op, hdev); | 2330 | cmd = pending_find(mgmt_op, hdev); |
2407 | if (!cmd) | 2331 | if (!cmd) |
2408 | goto unlock; | 2332 | goto unlock; |
2409 | 2333 | ||
@@ -2897,7 +2821,7 @@ static int disconnect(struct sock *sk, struct hci_dev *hdev, void *data, | |||
2897 | goto failed; | 2821 | goto failed; |
2898 | } | 2822 | } |
2899 | 2823 | ||
2900 | if (mgmt_pending_find(MGMT_OP_DISCONNECT, hdev)) { | 2824 | if (pending_find(MGMT_OP_DISCONNECT, hdev)) { |
2901 | err = mgmt_cmd_complete(sk, hdev->id, MGMT_OP_DISCONNECT, | 2825 | err = mgmt_cmd_complete(sk, hdev->id, MGMT_OP_DISCONNECT, |
2902 | MGMT_STATUS_BUSY, &rp, sizeof(rp)); | 2826 | MGMT_STATUS_BUSY, &rp, sizeof(rp)); |
2903 | goto failed; | 2827 | goto failed; |
@@ -3361,7 +3285,7 @@ static int cancel_pair_device(struct sock *sk, struct hci_dev *hdev, void *data, | |||
3361 | goto unlock; | 3285 | goto unlock; |
3362 | } | 3286 | } |
3363 | 3287 | ||
3364 | cmd = mgmt_pending_find(MGMT_OP_PAIR_DEVICE, hdev); | 3288 | cmd = pending_find(MGMT_OP_PAIR_DEVICE, hdev); |
3365 | if (!cmd) { | 3289 | if (!cmd) { |
3366 | err = mgmt_cmd_status(sk, hdev->id, MGMT_OP_CANCEL_PAIR_DEVICE, | 3290 | err = mgmt_cmd_status(sk, hdev->id, MGMT_OP_CANCEL_PAIR_DEVICE, |
3367 | MGMT_STATUS_INVALID_PARAMS); | 3291 | MGMT_STATUS_INVALID_PARAMS); |
@@ -3539,7 +3463,7 @@ static void set_name_complete(struct hci_dev *hdev, u8 status, u16 opcode) | |||
3539 | 3463 | ||
3540 | hci_dev_lock(hdev); | 3464 | hci_dev_lock(hdev); |
3541 | 3465 | ||
3542 | cmd = mgmt_pending_find(MGMT_OP_SET_LOCAL_NAME, hdev); | 3466 | cmd = pending_find(MGMT_OP_SET_LOCAL_NAME, hdev); |
3543 | if (!cmd) | 3467 | if (!cmd) |
3544 | goto unlock; | 3468 | goto unlock; |
3545 | 3469 | ||
@@ -3591,8 +3515,8 @@ static int set_local_name(struct sock *sk, struct hci_dev *hdev, void *data, | |||
3591 | if (err < 0) | 3515 | if (err < 0) |
3592 | goto failed; | 3516 | goto failed; |
3593 | 3517 | ||
3594 | err = mgmt_event(MGMT_EV_LOCAL_NAME_CHANGED, hdev, data, len, | 3518 | err = mgmt_generic_event(MGMT_EV_LOCAL_NAME_CHANGED, hdev, |
3595 | sk); | 3519 | data, len, sk); |
3596 | 3520 | ||
3597 | goto failed; | 3521 | goto failed; |
3598 | } | 3522 | } |
@@ -3649,7 +3573,7 @@ static int read_local_oob_data(struct sock *sk, struct hci_dev *hdev, | |||
3649 | goto unlock; | 3573 | goto unlock; |
3650 | } | 3574 | } |
3651 | 3575 | ||
3652 | if (mgmt_pending_find(MGMT_OP_READ_LOCAL_OOB_DATA, hdev)) { | 3576 | if (pending_find(MGMT_OP_READ_LOCAL_OOB_DATA, hdev)) { |
3653 | err = mgmt_cmd_status(sk, hdev->id, MGMT_OP_READ_LOCAL_OOB_DATA, | 3577 | err = mgmt_cmd_status(sk, hdev->id, MGMT_OP_READ_LOCAL_OOB_DATA, |
3654 | MGMT_STATUS_BUSY); | 3578 | MGMT_STATUS_BUSY); |
3655 | goto unlock; | 3579 | goto unlock; |
@@ -3819,93 +3743,129 @@ done: | |||
3819 | return err; | 3743 | return err; |
3820 | } | 3744 | } |
3821 | 3745 | ||
3822 | static bool trigger_discovery(struct hci_request *req, u8 *status) | 3746 | static bool trigger_bredr_inquiry(struct hci_request *req, u8 *status) |
3823 | { | 3747 | { |
3824 | struct hci_dev *hdev = req->hdev; | 3748 | struct hci_dev *hdev = req->hdev; |
3825 | struct hci_cp_le_set_scan_param param_cp; | 3749 | struct hci_cp_inquiry cp; |
3826 | struct hci_cp_le_set_scan_enable enable_cp; | ||
3827 | struct hci_cp_inquiry inq_cp; | ||
3828 | /* General inquiry access code (GIAC) */ | 3750 | /* General inquiry access code (GIAC) */ |
3829 | u8 lap[3] = { 0x33, 0x8b, 0x9e }; | 3751 | u8 lap[3] = { 0x33, 0x8b, 0x9e }; |
3752 | |||
3753 | *status = mgmt_bredr_support(hdev); | ||
3754 | if (*status) | ||
3755 | return false; | ||
3756 | |||
3757 | if (hci_dev_test_flag(hdev, HCI_INQUIRY)) { | ||
3758 | *status = MGMT_STATUS_BUSY; | ||
3759 | return false; | ||
3760 | } | ||
3761 | |||
3762 | hci_inquiry_cache_flush(hdev); | ||
3763 | |||
3764 | memset(&cp, 0, sizeof(cp)); | ||
3765 | memcpy(&cp.lap, lap, sizeof(cp.lap)); | ||
3766 | cp.length = DISCOV_BREDR_INQUIRY_LEN; | ||
3767 | |||
3768 | hci_req_add(req, HCI_OP_INQUIRY, sizeof(cp), &cp); | ||
3769 | |||
3770 | return true; | ||
3771 | } | ||
3772 | |||
3773 | static bool trigger_le_scan(struct hci_request *req, u16 interval, u8 *status) | ||
3774 | { | ||
3775 | struct hci_dev *hdev = req->hdev; | ||
3776 | struct hci_cp_le_set_scan_param param_cp; | ||
3777 | struct hci_cp_le_set_scan_enable enable_cp; | ||
3830 | u8 own_addr_type; | 3778 | u8 own_addr_type; |
3831 | int err; | 3779 | int err; |
3832 | 3780 | ||
3833 | switch (hdev->discovery.type) { | 3781 | *status = mgmt_le_support(hdev); |
3834 | case DISCOV_TYPE_BREDR: | 3782 | if (*status) |
3835 | *status = mgmt_bredr_support(hdev); | 3783 | return false; |
3836 | if (*status) | ||
3837 | return false; | ||
3838 | 3784 | ||
3839 | if (test_bit(HCI_INQUIRY, &hdev->flags)) { | 3785 | if (hci_dev_test_flag(hdev, HCI_LE_ADV)) { |
3840 | *status = MGMT_STATUS_BUSY; | 3786 | /* Don't let discovery abort an outgoing connection attempt |
3787 | * that's using directed advertising. | ||
3788 | */ | ||
3789 | if (hci_conn_hash_lookup_state(hdev, LE_LINK, BT_CONNECT)) { | ||
3790 | *status = MGMT_STATUS_REJECTED; | ||
3841 | return false; | 3791 | return false; |
3842 | } | 3792 | } |
3843 | 3793 | ||
3844 | hci_inquiry_cache_flush(hdev); | 3794 | disable_advertising(req); |
3795 | } | ||
3845 | 3796 | ||
3846 | memset(&inq_cp, 0, sizeof(inq_cp)); | 3797 | /* If controller is scanning, it means the background scanning is |
3847 | memcpy(&inq_cp.lap, lap, sizeof(inq_cp.lap)); | 3798 | * running. Thus, we should temporarily stop it in order to set the |
3848 | inq_cp.length = DISCOV_BREDR_INQUIRY_LEN; | 3799 | * discovery scanning parameters. |
3849 | hci_req_add(req, HCI_OP_INQUIRY, sizeof(inq_cp), &inq_cp); | 3800 | */ |
3850 | break; | 3801 | if (hci_dev_test_flag(hdev, HCI_LE_SCAN)) |
3802 | hci_req_add_le_scan_disable(req); | ||
3851 | 3803 | ||
3852 | case DISCOV_TYPE_LE: | 3804 | /* All active scans will be done with either a resolvable private |
3853 | case DISCOV_TYPE_INTERLEAVED: | 3805 | * address (when privacy feature has been enabled) or non-resolvable |
3854 | *status = mgmt_le_support(hdev); | 3806 | * private address. |
3855 | if (*status) | 3807 | */ |
3856 | return false; | 3808 | err = hci_update_random_address(req, true, &own_addr_type); |
3809 | if (err < 0) { | ||
3810 | *status = MGMT_STATUS_FAILED; | ||
3811 | return false; | ||
3812 | } | ||
3857 | 3813 | ||
3858 | if (hdev->discovery.type == DISCOV_TYPE_INTERLEAVED && | 3814 | memset(¶m_cp, 0, sizeof(param_cp)); |
3859 | !hci_dev_test_flag(hdev, HCI_BREDR_ENABLED)) { | 3815 | param_cp.type = LE_SCAN_ACTIVE; |
3860 | *status = MGMT_STATUS_NOT_SUPPORTED; | 3816 | param_cp.interval = cpu_to_le16(interval); |
3817 | param_cp.window = cpu_to_le16(DISCOV_LE_SCAN_WIN); | ||
3818 | param_cp.own_address_type = own_addr_type; | ||
3819 | |||
3820 | hci_req_add(req, HCI_OP_LE_SET_SCAN_PARAM, sizeof(param_cp), | ||
3821 | ¶m_cp); | ||
3822 | |||
3823 | memset(&enable_cp, 0, sizeof(enable_cp)); | ||
3824 | enable_cp.enable = LE_SCAN_ENABLE; | ||
3825 | enable_cp.filter_dup = LE_SCAN_FILTER_DUP_ENABLE; | ||
3826 | |||
3827 | hci_req_add(req, HCI_OP_LE_SET_SCAN_ENABLE, sizeof(enable_cp), | ||
3828 | &enable_cp); | ||
3829 | |||
3830 | return true; | ||
3831 | } | ||
3832 | |||
3833 | static bool trigger_discovery(struct hci_request *req, u8 *status) | ||
3834 | { | ||
3835 | struct hci_dev *hdev = req->hdev; | ||
3836 | |||
3837 | switch (hdev->discovery.type) { | ||
3838 | case DISCOV_TYPE_BREDR: | ||
3839 | if (!trigger_bredr_inquiry(req, status)) | ||
3861 | return false; | 3840 | return false; |
3862 | } | 3841 | break; |
3863 | 3842 | ||
3864 | if (hci_dev_test_flag(hdev, HCI_LE_ADV)) { | 3843 | case DISCOV_TYPE_INTERLEAVED: |
3865 | /* Don't let discovery abort an outgoing | 3844 | if (test_bit(HCI_QUIRK_SIMULTANEOUS_DISCOVERY, |
3866 | * connection attempt that's using directed | 3845 | &hdev->quirks)) { |
3867 | * advertising. | 3846 | /* During simultaneous discovery, we double LE scan |
3847 | * interval. We must leave some time for the controller | ||
3848 | * to do BR/EDR inquiry. | ||
3868 | */ | 3849 | */ |
3869 | if (hci_conn_hash_lookup_state(hdev, LE_LINK, | 3850 | if (!trigger_le_scan(req, DISCOV_LE_SCAN_INT * 2, |
3870 | BT_CONNECT)) { | 3851 | status)) |
3871 | *status = MGMT_STATUS_REJECTED; | ||
3872 | return false; | 3852 | return false; |
3873 | } | ||
3874 | |||
3875 | disable_advertising(req); | ||
3876 | } | ||
3877 | 3853 | ||
3878 | /* If controller is scanning, it means the background scanning | 3854 | if (!trigger_bredr_inquiry(req, status)) |
3879 | * is running. Thus, we should temporarily stop it in order to | 3855 | return false; |
3880 | * set the discovery scanning parameters. | ||
3881 | */ | ||
3882 | if (hci_dev_test_flag(hdev, HCI_LE_SCAN)) | ||
3883 | hci_req_add_le_scan_disable(req); | ||
3884 | 3856 | ||
3885 | memset(¶m_cp, 0, sizeof(param_cp)); | 3857 | return true; |
3858 | } | ||
3886 | 3859 | ||
3887 | /* All active scans will be done with either a resolvable | 3860 | if (!hci_dev_test_flag(hdev, HCI_BREDR_ENABLED)) { |
3888 | * private address (when privacy feature has been enabled) | 3861 | *status = MGMT_STATUS_NOT_SUPPORTED; |
3889 | * or non-resolvable private address. | ||
3890 | */ | ||
3891 | err = hci_update_random_address(req, true, &own_addr_type); | ||
3892 | if (err < 0) { | ||
3893 | *status = MGMT_STATUS_FAILED; | ||
3894 | return false; | 3862 | return false; |
3895 | } | 3863 | } |
3864 | /* fall through */ | ||
3896 | 3865 | ||
3897 | param_cp.type = LE_SCAN_ACTIVE; | 3866 | case DISCOV_TYPE_LE: |
3898 | param_cp.interval = cpu_to_le16(DISCOV_LE_SCAN_INT); | 3867 | if (!trigger_le_scan(req, DISCOV_LE_SCAN_INT, status)) |
3899 | param_cp.window = cpu_to_le16(DISCOV_LE_SCAN_WIN); | 3868 | return false; |
3900 | param_cp.own_address_type = own_addr_type; | ||
3901 | hci_req_add(req, HCI_OP_LE_SET_SCAN_PARAM, sizeof(param_cp), | ||
3902 | ¶m_cp); | ||
3903 | |||
3904 | memset(&enable_cp, 0, sizeof(enable_cp)); | ||
3905 | enable_cp.enable = LE_SCAN_ENABLE; | ||
3906 | enable_cp.filter_dup = LE_SCAN_FILTER_DUP_ENABLE; | ||
3907 | hci_req_add(req, HCI_OP_LE_SET_SCAN_ENABLE, sizeof(enable_cp), | ||
3908 | &enable_cp); | ||
3909 | break; | 3869 | break; |
3910 | 3870 | ||
3911 | default: | 3871 | default: |
@@ -3926,9 +3886,9 @@ static void start_discovery_complete(struct hci_dev *hdev, u8 status, | |||
3926 | 3886 | ||
3927 | hci_dev_lock(hdev); | 3887 | hci_dev_lock(hdev); |
3928 | 3888 | ||
3929 | cmd = mgmt_pending_find(MGMT_OP_START_DISCOVERY, hdev); | 3889 | cmd = pending_find(MGMT_OP_START_DISCOVERY, hdev); |
3930 | if (!cmd) | 3890 | if (!cmd) |
3931 | cmd = mgmt_pending_find(MGMT_OP_START_SERVICE_DISCOVERY, hdev); | 3891 | cmd = pending_find(MGMT_OP_START_SERVICE_DISCOVERY, hdev); |
3932 | 3892 | ||
3933 | if (cmd) { | 3893 | if (cmd) { |
3934 | cmd->cmd_complete(cmd, mgmt_status(status)); | 3894 | cmd->cmd_complete(cmd, mgmt_status(status)); |
@@ -3950,7 +3910,18 @@ static void start_discovery_complete(struct hci_dev *hdev, u8 status, | |||
3950 | timeout = msecs_to_jiffies(DISCOV_LE_TIMEOUT); | 3910 | timeout = msecs_to_jiffies(DISCOV_LE_TIMEOUT); |
3951 | break; | 3911 | break; |
3952 | case DISCOV_TYPE_INTERLEAVED: | 3912 | case DISCOV_TYPE_INTERLEAVED: |
3953 | timeout = msecs_to_jiffies(hdev->discov_interleaved_timeout); | 3913 | /* When running simultaneous discovery, the LE scanning time |
3914 | * should occupy the whole discovery time sine BR/EDR inquiry | ||
3915 | * and LE scanning are scheduled by the controller. | ||
3916 | * | ||
3917 | * For interleaving discovery in comparison, BR/EDR inquiry | ||
3918 | * and LE scanning are done sequentially with separate | ||
3919 | * timeouts. | ||
3920 | */ | ||
3921 | if (test_bit(HCI_QUIRK_SIMULTANEOUS_DISCOVERY, &hdev->quirks)) | ||
3922 | timeout = msecs_to_jiffies(DISCOV_LE_TIMEOUT); | ||
3923 | else | ||
3924 | timeout = msecs_to_jiffies(hdev->discov_interleaved_timeout); | ||
3954 | break; | 3925 | break; |
3955 | case DISCOV_TYPE_BREDR: | 3926 | case DISCOV_TYPE_BREDR: |
3956 | timeout = 0; | 3927 | timeout = 0; |
@@ -4172,7 +4143,7 @@ static void stop_discovery_complete(struct hci_dev *hdev, u8 status, u16 opcode) | |||
4172 | 4143 | ||
4173 | hci_dev_lock(hdev); | 4144 | hci_dev_lock(hdev); |
4174 | 4145 | ||
4175 | cmd = mgmt_pending_find(MGMT_OP_STOP_DISCOVERY, hdev); | 4146 | cmd = pending_find(MGMT_OP_STOP_DISCOVERY, hdev); |
4176 | if (cmd) { | 4147 | if (cmd) { |
4177 | cmd->cmd_complete(cmd, mgmt_status(status)); | 4148 | cmd->cmd_complete(cmd, mgmt_status(status)); |
4178 | mgmt_pending_remove(cmd); | 4149 | mgmt_pending_remove(cmd); |
@@ -4481,8 +4452,8 @@ static int set_advertising(struct sock *sk, struct hci_dev *hdev, void *data, | |||
4481 | goto unlock; | 4452 | goto unlock; |
4482 | } | 4453 | } |
4483 | 4454 | ||
4484 | if (mgmt_pending_find(MGMT_OP_SET_ADVERTISING, hdev) || | 4455 | if (pending_find(MGMT_OP_SET_ADVERTISING, hdev) || |
4485 | mgmt_pending_find(MGMT_OP_SET_LE, hdev)) { | 4456 | pending_find(MGMT_OP_SET_LE, hdev)) { |
4486 | err = mgmt_cmd_status(sk, hdev->id, MGMT_OP_SET_ADVERTISING, | 4457 | err = mgmt_cmd_status(sk, hdev->id, MGMT_OP_SET_ADVERTISING, |
4487 | MGMT_STATUS_BUSY); | 4458 | MGMT_STATUS_BUSY); |
4488 | goto unlock; | 4459 | goto unlock; |
@@ -4625,7 +4596,7 @@ static void fast_connectable_complete(struct hci_dev *hdev, u8 status, | |||
4625 | 4596 | ||
4626 | hci_dev_lock(hdev); | 4597 | hci_dev_lock(hdev); |
4627 | 4598 | ||
4628 | cmd = mgmt_pending_find(MGMT_OP_SET_FAST_CONNECTABLE, hdev); | 4599 | cmd = pending_find(MGMT_OP_SET_FAST_CONNECTABLE, hdev); |
4629 | if (!cmd) | 4600 | if (!cmd) |
4630 | goto unlock; | 4601 | goto unlock; |
4631 | 4602 | ||
@@ -4671,7 +4642,7 @@ static int set_fast_connectable(struct sock *sk, struct hci_dev *hdev, | |||
4671 | 4642 | ||
4672 | hci_dev_lock(hdev); | 4643 | hci_dev_lock(hdev); |
4673 | 4644 | ||
4674 | if (mgmt_pending_find(MGMT_OP_SET_FAST_CONNECTABLE, hdev)) { | 4645 | if (pending_find(MGMT_OP_SET_FAST_CONNECTABLE, hdev)) { |
4675 | err = mgmt_cmd_status(sk, hdev->id, MGMT_OP_SET_FAST_CONNECTABLE, | 4646 | err = mgmt_cmd_status(sk, hdev->id, MGMT_OP_SET_FAST_CONNECTABLE, |
4676 | MGMT_STATUS_BUSY); | 4647 | MGMT_STATUS_BUSY); |
4677 | goto unlock; | 4648 | goto unlock; |
@@ -4723,7 +4694,7 @@ static void set_bredr_complete(struct hci_dev *hdev, u8 status, u16 opcode) | |||
4723 | 4694 | ||
4724 | hci_dev_lock(hdev); | 4695 | hci_dev_lock(hdev); |
4725 | 4696 | ||
4726 | cmd = mgmt_pending_find(MGMT_OP_SET_BREDR, hdev); | 4697 | cmd = pending_find(MGMT_OP_SET_BREDR, hdev); |
4727 | if (!cmd) | 4698 | if (!cmd) |
4728 | goto unlock; | 4699 | goto unlock; |
4729 | 4700 | ||
@@ -4823,7 +4794,7 @@ static int set_bredr(struct sock *sk, struct hci_dev *hdev, void *data, u16 len) | |||
4823 | } | 4794 | } |
4824 | } | 4795 | } |
4825 | 4796 | ||
4826 | if (mgmt_pending_find(MGMT_OP_SET_BREDR, hdev)) { | 4797 | if (pending_find(MGMT_OP_SET_BREDR, hdev)) { |
4827 | err = mgmt_cmd_status(sk, hdev->id, MGMT_OP_SET_BREDR, | 4798 | err = mgmt_cmd_status(sk, hdev->id, MGMT_OP_SET_BREDR, |
4828 | MGMT_STATUS_BUSY); | 4799 | MGMT_STATUS_BUSY); |
4829 | goto unlock; | 4800 | goto unlock; |
@@ -4868,7 +4839,7 @@ static void sc_enable_complete(struct hci_dev *hdev, u8 status, u16 opcode) | |||
4868 | 4839 | ||
4869 | hci_dev_lock(hdev); | 4840 | hci_dev_lock(hdev); |
4870 | 4841 | ||
4871 | cmd = mgmt_pending_find(MGMT_OP_SET_SECURE_CONN, hdev); | 4842 | cmd = pending_find(MGMT_OP_SET_SECURE_CONN, hdev); |
4872 | if (!cmd) | 4843 | if (!cmd) |
4873 | goto unlock; | 4844 | goto unlock; |
4874 | 4845 | ||
@@ -4959,7 +4930,7 @@ static int set_secure_conn(struct sock *sk, struct hci_dev *hdev, | |||
4959 | goto failed; | 4930 | goto failed; |
4960 | } | 4931 | } |
4961 | 4932 | ||
4962 | if (mgmt_pending_find(MGMT_OP_SET_SECURE_CONN, hdev)) { | 4933 | if (pending_find(MGMT_OP_SET_SECURE_CONN, hdev)) { |
4963 | err = mgmt_cmd_status(sk, hdev->id, MGMT_OP_SET_SECURE_CONN, | 4934 | err = mgmt_cmd_status(sk, hdev->id, MGMT_OP_SET_SECURE_CONN, |
4964 | MGMT_STATUS_BUSY); | 4935 | MGMT_STATUS_BUSY); |
4965 | goto failed; | 4936 | goto failed; |
@@ -5352,7 +5323,7 @@ static void conn_info_refresh_complete(struct hci_dev *hdev, u8 hci_status, | |||
5352 | goto unlock; | 5323 | goto unlock; |
5353 | } | 5324 | } |
5354 | 5325 | ||
5355 | cmd = mgmt_pending_find_data(MGMT_OP_GET_CONN_INFO, hdev, conn); | 5326 | cmd = pending_find_data(MGMT_OP_GET_CONN_INFO, hdev, conn); |
5356 | if (!cmd) | 5327 | if (!cmd) |
5357 | goto unlock; | 5328 | goto unlock; |
5358 | 5329 | ||
@@ -5405,7 +5376,7 @@ static int get_conn_info(struct sock *sk, struct hci_dev *hdev, void *data, | |||
5405 | goto unlock; | 5376 | goto unlock; |
5406 | } | 5377 | } |
5407 | 5378 | ||
5408 | if (mgmt_pending_find_data(MGMT_OP_GET_CONN_INFO, hdev, conn)) { | 5379 | if (pending_find_data(MGMT_OP_GET_CONN_INFO, hdev, conn)) { |
5409 | err = mgmt_cmd_complete(sk, hdev->id, MGMT_OP_GET_CONN_INFO, | 5380 | err = mgmt_cmd_complete(sk, hdev->id, MGMT_OP_GET_CONN_INFO, |
5410 | MGMT_STATUS_BUSY, &rp, sizeof(rp)); | 5381 | MGMT_STATUS_BUSY, &rp, sizeof(rp)); |
5411 | goto unlock; | 5382 | goto unlock; |
@@ -5541,7 +5512,7 @@ static void get_clock_info_complete(struct hci_dev *hdev, u8 status, u16 opcode) | |||
5541 | conn = NULL; | 5512 | conn = NULL; |
5542 | } | 5513 | } |
5543 | 5514 | ||
5544 | cmd = mgmt_pending_find_data(MGMT_OP_GET_CLOCK_INFO, hdev, conn); | 5515 | cmd = pending_find_data(MGMT_OP_GET_CLOCK_INFO, hdev, conn); |
5545 | if (!cmd) | 5516 | if (!cmd) |
5546 | goto unlock; | 5517 | goto unlock; |
5547 | 5518 | ||
@@ -5707,7 +5678,7 @@ static void add_device_complete(struct hci_dev *hdev, u8 status, u16 opcode) | |||
5707 | 5678 | ||
5708 | hci_dev_lock(hdev); | 5679 | hci_dev_lock(hdev); |
5709 | 5680 | ||
5710 | cmd = mgmt_pending_find(MGMT_OP_ADD_DEVICE, hdev); | 5681 | cmd = pending_find(MGMT_OP_ADD_DEVICE, hdev); |
5711 | if (!cmd) | 5682 | if (!cmd) |
5712 | goto unlock; | 5683 | goto unlock; |
5713 | 5684 | ||
@@ -5830,7 +5801,7 @@ static void remove_device_complete(struct hci_dev *hdev, u8 status, u16 opcode) | |||
5830 | 5801 | ||
5831 | hci_dev_lock(hdev); | 5802 | hci_dev_lock(hdev); |
5832 | 5803 | ||
5833 | cmd = mgmt_pending_find(MGMT_OP_REMOVE_DEVICE, hdev); | 5804 | cmd = pending_find(MGMT_OP_REMOVE_DEVICE, hdev); |
5834 | if (!cmd) | 5805 | if (!cmd) |
5835 | goto unlock; | 5806 | goto unlock; |
5836 | 5807 | ||
@@ -6162,215 +6133,339 @@ unlock: | |||
6162 | return err; | 6133 | return err; |
6163 | } | 6134 | } |
6164 | 6135 | ||
6165 | static const struct hci_mgmt_handler mgmt_handlers[] = { | 6136 | static inline u16 eir_append_data(u8 *eir, u16 eir_len, u8 type, u8 *data, |
6166 | { NULL }, /* 0x0000 (no command) */ | 6137 | u8 data_len) |
6167 | { read_version, MGMT_READ_VERSION_SIZE, | ||
6168 | HCI_MGMT_NO_HDEV }, | ||
6169 | { read_commands, MGMT_READ_COMMANDS_SIZE, | ||
6170 | HCI_MGMT_NO_HDEV }, | ||
6171 | { read_index_list, MGMT_READ_INDEX_LIST_SIZE, | ||
6172 | HCI_MGMT_NO_HDEV }, | ||
6173 | { read_controller_info, MGMT_READ_INFO_SIZE, 0 }, | ||
6174 | { set_powered, MGMT_SETTING_SIZE, 0 }, | ||
6175 | { set_discoverable, MGMT_SET_DISCOVERABLE_SIZE, 0 }, | ||
6176 | { set_connectable, MGMT_SETTING_SIZE, 0 }, | ||
6177 | { set_fast_connectable, MGMT_SETTING_SIZE, 0 }, | ||
6178 | { set_bondable, MGMT_SETTING_SIZE, 0 }, | ||
6179 | { set_link_security, MGMT_SETTING_SIZE, 0 }, | ||
6180 | { set_ssp, MGMT_SETTING_SIZE, 0 }, | ||
6181 | { set_hs, MGMT_SETTING_SIZE, 0 }, | ||
6182 | { set_le, MGMT_SETTING_SIZE, 0 }, | ||
6183 | { set_dev_class, MGMT_SET_DEV_CLASS_SIZE, 0 }, | ||
6184 | { set_local_name, MGMT_SET_LOCAL_NAME_SIZE, 0 }, | ||
6185 | { add_uuid, MGMT_ADD_UUID_SIZE, 0 }, | ||
6186 | { remove_uuid, MGMT_REMOVE_UUID_SIZE, 0 }, | ||
6187 | { load_link_keys, MGMT_LOAD_LINK_KEYS_SIZE, | ||
6188 | HCI_MGMT_VAR_LEN }, | ||
6189 | { load_long_term_keys, MGMT_LOAD_LONG_TERM_KEYS_SIZE, | ||
6190 | HCI_MGMT_VAR_LEN }, | ||
6191 | { disconnect, MGMT_DISCONNECT_SIZE, 0 }, | ||
6192 | { get_connections, MGMT_GET_CONNECTIONS_SIZE, 0 }, | ||
6193 | { pin_code_reply, MGMT_PIN_CODE_REPLY_SIZE, 0 }, | ||
6194 | { pin_code_neg_reply, MGMT_PIN_CODE_NEG_REPLY_SIZE, 0 }, | ||
6195 | { set_io_capability, MGMT_SET_IO_CAPABILITY_SIZE, 0 }, | ||
6196 | { pair_device, MGMT_PAIR_DEVICE_SIZE, 0 }, | ||
6197 | { cancel_pair_device, MGMT_CANCEL_PAIR_DEVICE_SIZE, 0 }, | ||
6198 | { unpair_device, MGMT_UNPAIR_DEVICE_SIZE, 0 }, | ||
6199 | { user_confirm_reply, MGMT_USER_CONFIRM_REPLY_SIZE, 0 }, | ||
6200 | { user_confirm_neg_reply, MGMT_USER_CONFIRM_NEG_REPLY_SIZE, 0 }, | ||
6201 | { user_passkey_reply, MGMT_USER_PASSKEY_REPLY_SIZE, 0 }, | ||
6202 | { user_passkey_neg_reply, MGMT_USER_PASSKEY_NEG_REPLY_SIZE, 0 }, | ||
6203 | { read_local_oob_data, MGMT_READ_LOCAL_OOB_DATA_SIZE }, | ||
6204 | { add_remote_oob_data, MGMT_ADD_REMOTE_OOB_DATA_SIZE, | ||
6205 | HCI_MGMT_VAR_LEN }, | ||
6206 | { remove_remote_oob_data, MGMT_REMOVE_REMOTE_OOB_DATA_SIZE, 0 }, | ||
6207 | { start_discovery, MGMT_START_DISCOVERY_SIZE, 0 }, | ||
6208 | { stop_discovery, MGMT_STOP_DISCOVERY_SIZE, 0 }, | ||
6209 | { confirm_name, MGMT_CONFIRM_NAME_SIZE, 0 }, | ||
6210 | { block_device, MGMT_BLOCK_DEVICE_SIZE, 0 }, | ||
6211 | { unblock_device, MGMT_UNBLOCK_DEVICE_SIZE, 0 }, | ||
6212 | { set_device_id, MGMT_SET_DEVICE_ID_SIZE, 0 }, | ||
6213 | { set_advertising, MGMT_SETTING_SIZE, 0 }, | ||
6214 | { set_bredr, MGMT_SETTING_SIZE, 0 }, | ||
6215 | { set_static_address, MGMT_SET_STATIC_ADDRESS_SIZE, 0 }, | ||
6216 | { set_scan_params, MGMT_SET_SCAN_PARAMS_SIZE, 0 }, | ||
6217 | { set_secure_conn, MGMT_SETTING_SIZE, 0 }, | ||
6218 | { set_debug_keys, MGMT_SETTING_SIZE, 0 }, | ||
6219 | { set_privacy, MGMT_SET_PRIVACY_SIZE, 0 }, | ||
6220 | { load_irks, MGMT_LOAD_IRKS_SIZE, | ||
6221 | HCI_MGMT_VAR_LEN }, | ||
6222 | { get_conn_info, MGMT_GET_CONN_INFO_SIZE, 0 }, | ||
6223 | { get_clock_info, MGMT_GET_CLOCK_INFO_SIZE, 0 }, | ||
6224 | { add_device, MGMT_ADD_DEVICE_SIZE, 0 }, | ||
6225 | { remove_device, MGMT_REMOVE_DEVICE_SIZE, 0 }, | ||
6226 | { load_conn_param, MGMT_LOAD_CONN_PARAM_SIZE, | ||
6227 | HCI_MGMT_VAR_LEN }, | ||
6228 | { read_unconf_index_list, MGMT_READ_UNCONF_INDEX_LIST_SIZE, | ||
6229 | HCI_MGMT_NO_HDEV }, | ||
6230 | { read_config_info, MGMT_READ_CONFIG_INFO_SIZE, | ||
6231 | HCI_MGMT_UNCONFIGURED }, | ||
6232 | { set_external_config, MGMT_SET_EXTERNAL_CONFIG_SIZE, | ||
6233 | HCI_MGMT_UNCONFIGURED }, | ||
6234 | { set_public_address, MGMT_SET_PUBLIC_ADDRESS_SIZE, | ||
6235 | HCI_MGMT_UNCONFIGURED }, | ||
6236 | { start_service_discovery, MGMT_START_SERVICE_DISCOVERY_SIZE, | ||
6237 | HCI_MGMT_VAR_LEN }, | ||
6238 | }; | ||
6239 | |||
6240 | int mgmt_control(struct hci_mgmt_chan *chan, struct sock *sk, | ||
6241 | struct msghdr *msg, size_t msglen) | ||
6242 | { | 6138 | { |
6243 | void *buf; | 6139 | eir[eir_len++] = sizeof(type) + data_len; |
6244 | u8 *cp; | 6140 | eir[eir_len++] = type; |
6245 | struct mgmt_hdr *hdr; | 6141 | memcpy(&eir[eir_len], data, data_len); |
6246 | u16 opcode, index, len; | 6142 | eir_len += data_len; |
6247 | struct hci_dev *hdev = NULL; | ||
6248 | const struct hci_mgmt_handler *handler; | ||
6249 | bool var_len, no_hdev; | ||
6250 | int err; | ||
6251 | 6143 | ||
6252 | BT_DBG("got %zu bytes", msglen); | 6144 | return eir_len; |
6145 | } | ||
6253 | 6146 | ||
6254 | if (msglen < sizeof(*hdr)) | 6147 | static int read_local_oob_ext_data(struct sock *sk, struct hci_dev *hdev, |
6255 | return -EINVAL; | 6148 | void *data, u16 data_len) |
6149 | { | ||
6150 | struct mgmt_cp_read_local_oob_ext_data *cp = data; | ||
6151 | struct mgmt_rp_read_local_oob_ext_data *rp; | ||
6152 | size_t rp_len; | ||
6153 | u16 eir_len; | ||
6154 | u8 status, flags, role, addr[7], hash[16], rand[16]; | ||
6155 | int err; | ||
6256 | 6156 | ||
6257 | buf = kmalloc(msglen, GFP_KERNEL); | 6157 | BT_DBG("%s", hdev->name); |
6258 | if (!buf) | ||
6259 | return -ENOMEM; | ||
6260 | 6158 | ||
6261 | if (memcpy_from_msg(buf, msg, msglen)) { | 6159 | if (!hdev_is_powered(hdev)) |
6262 | err = -EFAULT; | 6160 | return mgmt_cmd_complete(sk, hdev->id, |
6263 | goto done; | 6161 | MGMT_OP_READ_LOCAL_OOB_EXT_DATA, |
6162 | MGMT_STATUS_NOT_POWERED, | ||
6163 | &cp->type, sizeof(cp->type)); | ||
6164 | |||
6165 | switch (cp->type) { | ||
6166 | case BIT(BDADDR_BREDR): | ||
6167 | status = mgmt_bredr_support(hdev); | ||
6168 | if (status) | ||
6169 | return mgmt_cmd_complete(sk, hdev->id, | ||
6170 | MGMT_OP_READ_LOCAL_OOB_EXT_DATA, | ||
6171 | status, &cp->type, | ||
6172 | sizeof(cp->type)); | ||
6173 | eir_len = 5; | ||
6174 | break; | ||
6175 | case (BIT(BDADDR_LE_PUBLIC) | BIT(BDADDR_LE_RANDOM)): | ||
6176 | status = mgmt_le_support(hdev); | ||
6177 | if (status) | ||
6178 | return mgmt_cmd_complete(sk, hdev->id, | ||
6179 | MGMT_OP_READ_LOCAL_OOB_EXT_DATA, | ||
6180 | status, &cp->type, | ||
6181 | sizeof(cp->type)); | ||
6182 | eir_len = 9 + 3 + 18 + 18 + 3; | ||
6183 | break; | ||
6184 | default: | ||
6185 | return mgmt_cmd_complete(sk, hdev->id, | ||
6186 | MGMT_OP_READ_LOCAL_OOB_EXT_DATA, | ||
6187 | MGMT_STATUS_INVALID_PARAMS, | ||
6188 | &cp->type, sizeof(cp->type)); | ||
6264 | } | 6189 | } |
6265 | 6190 | ||
6266 | hdr = buf; | 6191 | hci_dev_lock(hdev); |
6267 | opcode = __le16_to_cpu(hdr->opcode); | ||
6268 | index = __le16_to_cpu(hdr->index); | ||
6269 | len = __le16_to_cpu(hdr->len); | ||
6270 | |||
6271 | if (len != msglen - sizeof(*hdr)) { | ||
6272 | err = -EINVAL; | ||
6273 | goto done; | ||
6274 | } | ||
6275 | 6192 | ||
6276 | if (opcode >= chan->handler_count || | 6193 | rp_len = sizeof(*rp) + eir_len; |
6277 | chan->handlers[opcode].func == NULL) { | 6194 | rp = kmalloc(rp_len, GFP_ATOMIC); |
6278 | BT_DBG("Unknown op %u", opcode); | 6195 | if (!rp) { |
6279 | err = mgmt_cmd_status(sk, index, opcode, | 6196 | hci_dev_unlock(hdev); |
6280 | MGMT_STATUS_UNKNOWN_COMMAND); | 6197 | return -ENOMEM; |
6281 | goto done; | ||
6282 | } | 6198 | } |
6283 | 6199 | ||
6284 | handler = &chan->handlers[opcode]; | 6200 | eir_len = 0; |
6285 | 6201 | switch (cp->type) { | |
6286 | if (index != MGMT_INDEX_NONE) { | 6202 | case BIT(BDADDR_BREDR): |
6287 | hdev = hci_dev_get(index); | 6203 | eir_len = eir_append_data(rp->eir, eir_len, EIR_CLASS_OF_DEV, |
6288 | if (!hdev) { | 6204 | hdev->dev_class, 3); |
6289 | err = mgmt_cmd_status(sk, index, opcode, | 6205 | break; |
6290 | MGMT_STATUS_INVALID_INDEX); | 6206 | case (BIT(BDADDR_LE_PUBLIC) | BIT(BDADDR_LE_RANDOM)): |
6207 | if (hci_dev_test_flag(hdev, HCI_SC_ENABLED) && | ||
6208 | smp_generate_oob(hdev, hash, rand) < 0) { | ||
6209 | hci_dev_unlock(hdev); | ||
6210 | err = mgmt_cmd_complete(sk, hdev->id, | ||
6211 | MGMT_OP_READ_LOCAL_OOB_EXT_DATA, | ||
6212 | MGMT_STATUS_FAILED, | ||
6213 | &cp->type, sizeof(cp->type)); | ||
6291 | goto done; | 6214 | goto done; |
6292 | } | 6215 | } |
6293 | 6216 | ||
6294 | if (hci_dev_test_flag(hdev, HCI_SETUP) || | 6217 | if (hci_dev_test_flag(hdev, HCI_PRIVACY)) { |
6295 | hci_dev_test_flag(hdev, HCI_CONFIG) || | 6218 | memcpy(addr, &hdev->rpa, 6); |
6296 | hci_dev_test_flag(hdev, HCI_USER_CHANNEL)) { | 6219 | addr[6] = 0x01; |
6297 | err = mgmt_cmd_status(sk, index, opcode, | 6220 | } else if (hci_dev_test_flag(hdev, HCI_FORCE_STATIC_ADDR) || |
6298 | MGMT_STATUS_INVALID_INDEX); | 6221 | !bacmp(&hdev->bdaddr, BDADDR_ANY) || |
6299 | goto done; | 6222 | (!hci_dev_test_flag(hdev, HCI_BREDR_ENABLED) && |
6223 | bacmp(&hdev->static_addr, BDADDR_ANY))) { | ||
6224 | memcpy(addr, &hdev->static_addr, 6); | ||
6225 | addr[6] = 0x01; | ||
6226 | } else { | ||
6227 | memcpy(addr, &hdev->bdaddr, 6); | ||
6228 | addr[6] = 0x00; | ||
6300 | } | 6229 | } |
6301 | 6230 | ||
6302 | if (hci_dev_test_flag(hdev, HCI_UNCONFIGURED) && | 6231 | eir_len = eir_append_data(rp->eir, eir_len, EIR_LE_BDADDR, |
6303 | !(handler->flags & HCI_MGMT_UNCONFIGURED)) { | 6232 | addr, sizeof(addr)); |
6304 | err = mgmt_cmd_status(sk, index, opcode, | 6233 | |
6305 | MGMT_STATUS_INVALID_INDEX); | 6234 | if (hci_dev_test_flag(hdev, HCI_ADVERTISING)) |
6306 | goto done; | 6235 | role = 0x02; |
6236 | else | ||
6237 | role = 0x01; | ||
6238 | |||
6239 | eir_len = eir_append_data(rp->eir, eir_len, EIR_LE_ROLE, | ||
6240 | &role, sizeof(role)); | ||
6241 | |||
6242 | if (hci_dev_test_flag(hdev, HCI_SC_ENABLED)) { | ||
6243 | eir_len = eir_append_data(rp->eir, eir_len, | ||
6244 | EIR_LE_SC_CONFIRM, | ||
6245 | hash, sizeof(hash)); | ||
6246 | |||
6247 | eir_len = eir_append_data(rp->eir, eir_len, | ||
6248 | EIR_LE_SC_RANDOM, | ||
6249 | rand, sizeof(rand)); | ||
6307 | } | 6250 | } |
6308 | } | ||
6309 | 6251 | ||
6310 | no_hdev = (handler->flags & HCI_MGMT_NO_HDEV); | 6252 | flags = get_adv_discov_flags(hdev); |
6311 | if (no_hdev != !hdev) { | ||
6312 | err = mgmt_cmd_status(sk, index, opcode, | ||
6313 | MGMT_STATUS_INVALID_INDEX); | ||
6314 | goto done; | ||
6315 | } | ||
6316 | 6253 | ||
6317 | var_len = (handler->flags & HCI_MGMT_VAR_LEN); | 6254 | if (!hci_dev_test_flag(hdev, HCI_BREDR_ENABLED)) |
6318 | if ((var_len && len < handler->data_len) || | 6255 | flags |= LE_AD_NO_BREDR; |
6319 | (!var_len && len != handler->data_len)) { | 6256 | |
6320 | err = mgmt_cmd_status(sk, index, opcode, | 6257 | eir_len = eir_append_data(rp->eir, eir_len, EIR_FLAGS, |
6321 | MGMT_STATUS_INVALID_PARAMS); | 6258 | &flags, sizeof(flags)); |
6322 | goto done; | 6259 | break; |
6323 | } | 6260 | } |
6324 | 6261 | ||
6325 | if (hdev) | 6262 | rp->type = cp->type; |
6326 | mgmt_init_hdev(sk, hdev); | 6263 | rp->eir_len = cpu_to_le16(eir_len); |
6327 | 6264 | ||
6328 | cp = buf + sizeof(*hdr); | 6265 | hci_dev_unlock(hdev); |
6266 | |||
6267 | hci_sock_set_flag(sk, HCI_MGMT_OOB_DATA_EVENTS); | ||
6329 | 6268 | ||
6330 | err = handler->func(sk, hdev, cp, len); | 6269 | err = mgmt_cmd_complete(sk, hdev->id, MGMT_OP_READ_LOCAL_OOB_EXT_DATA, |
6270 | MGMT_STATUS_SUCCESS, rp, sizeof(*rp) + eir_len); | ||
6331 | if (err < 0) | 6271 | if (err < 0) |
6332 | goto done; | 6272 | goto done; |
6333 | 6273 | ||
6334 | err = msglen; | 6274 | err = mgmt_limited_event(MGMT_EV_LOCAL_OOB_DATA_UPDATED, hdev, |
6275 | rp, sizeof(*rp) + eir_len, | ||
6276 | HCI_MGMT_OOB_DATA_EVENTS, sk); | ||
6335 | 6277 | ||
6336 | done: | 6278 | done: |
6337 | if (hdev) | 6279 | kfree(rp); |
6338 | hci_dev_put(hdev); | ||
6339 | 6280 | ||
6340 | kfree(buf); | ||
6341 | return err; | 6281 | return err; |
6342 | } | 6282 | } |
6343 | 6283 | ||
6284 | static int read_adv_features(struct sock *sk, struct hci_dev *hdev, | ||
6285 | void *data, u16 data_len) | ||
6286 | { | ||
6287 | struct mgmt_rp_read_adv_features *rp; | ||
6288 | size_t rp_len; | ||
6289 | int err; | ||
6290 | |||
6291 | BT_DBG("%s", hdev->name); | ||
6292 | |||
6293 | hci_dev_lock(hdev); | ||
6294 | |||
6295 | rp_len = sizeof(*rp); | ||
6296 | rp = kmalloc(rp_len, GFP_ATOMIC); | ||
6297 | if (!rp) { | ||
6298 | hci_dev_unlock(hdev); | ||
6299 | return -ENOMEM; | ||
6300 | } | ||
6301 | |||
6302 | rp->supported_flags = cpu_to_le32(0); | ||
6303 | rp->max_adv_data_len = 31; | ||
6304 | rp->max_scan_rsp_len = 31; | ||
6305 | rp->max_instances = 0; | ||
6306 | rp->num_instances = 0; | ||
6307 | |||
6308 | hci_dev_unlock(hdev); | ||
6309 | |||
6310 | err = mgmt_cmd_complete(sk, hdev->id, MGMT_OP_READ_ADV_FEATURES, | ||
6311 | MGMT_STATUS_SUCCESS, rp, rp_len); | ||
6312 | |||
6313 | kfree(rp); | ||
6314 | |||
6315 | return err; | ||
6316 | } | ||
6317 | |||
6318 | static const struct hci_mgmt_handler mgmt_handlers[] = { | ||
6319 | { NULL }, /* 0x0000 (no command) */ | ||
6320 | { read_version, MGMT_READ_VERSION_SIZE, | ||
6321 | HCI_MGMT_NO_HDEV | | ||
6322 | HCI_MGMT_UNTRUSTED }, | ||
6323 | { read_commands, MGMT_READ_COMMANDS_SIZE, | ||
6324 | HCI_MGMT_NO_HDEV | | ||
6325 | HCI_MGMT_UNTRUSTED }, | ||
6326 | { read_index_list, MGMT_READ_INDEX_LIST_SIZE, | ||
6327 | HCI_MGMT_NO_HDEV | | ||
6328 | HCI_MGMT_UNTRUSTED }, | ||
6329 | { read_controller_info, MGMT_READ_INFO_SIZE, | ||
6330 | HCI_MGMT_UNTRUSTED }, | ||
6331 | { set_powered, MGMT_SETTING_SIZE }, | ||
6332 | { set_discoverable, MGMT_SET_DISCOVERABLE_SIZE }, | ||
6333 | { set_connectable, MGMT_SETTING_SIZE }, | ||
6334 | { set_fast_connectable, MGMT_SETTING_SIZE }, | ||
6335 | { set_bondable, MGMT_SETTING_SIZE }, | ||
6336 | { set_link_security, MGMT_SETTING_SIZE }, | ||
6337 | { set_ssp, MGMT_SETTING_SIZE }, | ||
6338 | { set_hs, MGMT_SETTING_SIZE }, | ||
6339 | { set_le, MGMT_SETTING_SIZE }, | ||
6340 | { set_dev_class, MGMT_SET_DEV_CLASS_SIZE }, | ||
6341 | { set_local_name, MGMT_SET_LOCAL_NAME_SIZE }, | ||
6342 | { add_uuid, MGMT_ADD_UUID_SIZE }, | ||
6343 | { remove_uuid, MGMT_REMOVE_UUID_SIZE }, | ||
6344 | { load_link_keys, MGMT_LOAD_LINK_KEYS_SIZE, | ||
6345 | HCI_MGMT_VAR_LEN }, | ||
6346 | { load_long_term_keys, MGMT_LOAD_LONG_TERM_KEYS_SIZE, | ||
6347 | HCI_MGMT_VAR_LEN }, | ||
6348 | { disconnect, MGMT_DISCONNECT_SIZE }, | ||
6349 | { get_connections, MGMT_GET_CONNECTIONS_SIZE }, | ||
6350 | { pin_code_reply, MGMT_PIN_CODE_REPLY_SIZE }, | ||
6351 | { pin_code_neg_reply, MGMT_PIN_CODE_NEG_REPLY_SIZE }, | ||
6352 | { set_io_capability, MGMT_SET_IO_CAPABILITY_SIZE }, | ||
6353 | { pair_device, MGMT_PAIR_DEVICE_SIZE }, | ||
6354 | { cancel_pair_device, MGMT_CANCEL_PAIR_DEVICE_SIZE }, | ||
6355 | { unpair_device, MGMT_UNPAIR_DEVICE_SIZE }, | ||
6356 | { user_confirm_reply, MGMT_USER_CONFIRM_REPLY_SIZE }, | ||
6357 | { user_confirm_neg_reply, MGMT_USER_CONFIRM_NEG_REPLY_SIZE }, | ||
6358 | { user_passkey_reply, MGMT_USER_PASSKEY_REPLY_SIZE }, | ||
6359 | { user_passkey_neg_reply, MGMT_USER_PASSKEY_NEG_REPLY_SIZE }, | ||
6360 | { read_local_oob_data, MGMT_READ_LOCAL_OOB_DATA_SIZE }, | ||
6361 | { add_remote_oob_data, MGMT_ADD_REMOTE_OOB_DATA_SIZE, | ||
6362 | HCI_MGMT_VAR_LEN }, | ||
6363 | { remove_remote_oob_data, MGMT_REMOVE_REMOTE_OOB_DATA_SIZE }, | ||
6364 | { start_discovery, MGMT_START_DISCOVERY_SIZE }, | ||
6365 | { stop_discovery, MGMT_STOP_DISCOVERY_SIZE }, | ||
6366 | { confirm_name, MGMT_CONFIRM_NAME_SIZE }, | ||
6367 | { block_device, MGMT_BLOCK_DEVICE_SIZE }, | ||
6368 | { unblock_device, MGMT_UNBLOCK_DEVICE_SIZE }, | ||
6369 | { set_device_id, MGMT_SET_DEVICE_ID_SIZE }, | ||
6370 | { set_advertising, MGMT_SETTING_SIZE }, | ||
6371 | { set_bredr, MGMT_SETTING_SIZE }, | ||
6372 | { set_static_address, MGMT_SET_STATIC_ADDRESS_SIZE }, | ||
6373 | { set_scan_params, MGMT_SET_SCAN_PARAMS_SIZE }, | ||
6374 | { set_secure_conn, MGMT_SETTING_SIZE }, | ||
6375 | { set_debug_keys, MGMT_SETTING_SIZE }, | ||
6376 | { set_privacy, MGMT_SET_PRIVACY_SIZE }, | ||
6377 | { load_irks, MGMT_LOAD_IRKS_SIZE, | ||
6378 | HCI_MGMT_VAR_LEN }, | ||
6379 | { get_conn_info, MGMT_GET_CONN_INFO_SIZE }, | ||
6380 | { get_clock_info, MGMT_GET_CLOCK_INFO_SIZE }, | ||
6381 | { add_device, MGMT_ADD_DEVICE_SIZE }, | ||
6382 | { remove_device, MGMT_REMOVE_DEVICE_SIZE }, | ||
6383 | { load_conn_param, MGMT_LOAD_CONN_PARAM_SIZE, | ||
6384 | HCI_MGMT_VAR_LEN }, | ||
6385 | { read_unconf_index_list, MGMT_READ_UNCONF_INDEX_LIST_SIZE, | ||
6386 | HCI_MGMT_NO_HDEV | | ||
6387 | HCI_MGMT_UNTRUSTED }, | ||
6388 | { read_config_info, MGMT_READ_CONFIG_INFO_SIZE, | ||
6389 | HCI_MGMT_UNCONFIGURED | | ||
6390 | HCI_MGMT_UNTRUSTED }, | ||
6391 | { set_external_config, MGMT_SET_EXTERNAL_CONFIG_SIZE, | ||
6392 | HCI_MGMT_UNCONFIGURED }, | ||
6393 | { set_public_address, MGMT_SET_PUBLIC_ADDRESS_SIZE, | ||
6394 | HCI_MGMT_UNCONFIGURED }, | ||
6395 | { start_service_discovery, MGMT_START_SERVICE_DISCOVERY_SIZE, | ||
6396 | HCI_MGMT_VAR_LEN }, | ||
6397 | { read_local_oob_ext_data, MGMT_READ_LOCAL_OOB_EXT_DATA_SIZE }, | ||
6398 | { read_ext_index_list, MGMT_READ_EXT_INDEX_LIST_SIZE, | ||
6399 | HCI_MGMT_NO_HDEV | | ||
6400 | HCI_MGMT_UNTRUSTED }, | ||
6401 | { read_adv_features, MGMT_READ_ADV_FEATURES_SIZE }, | ||
6402 | }; | ||
6403 | |||
6344 | void mgmt_index_added(struct hci_dev *hdev) | 6404 | void mgmt_index_added(struct hci_dev *hdev) |
6345 | { | 6405 | { |
6346 | if (hdev->dev_type != HCI_BREDR) | 6406 | struct mgmt_ev_ext_index ev; |
6347 | return; | ||
6348 | 6407 | ||
6349 | if (test_bit(HCI_QUIRK_RAW_DEVICE, &hdev->quirks)) | 6408 | if (test_bit(HCI_QUIRK_RAW_DEVICE, &hdev->quirks)) |
6350 | return; | 6409 | return; |
6351 | 6410 | ||
6352 | if (hci_dev_test_flag(hdev, HCI_UNCONFIGURED)) | 6411 | switch (hdev->dev_type) { |
6353 | mgmt_event(MGMT_EV_UNCONF_INDEX_ADDED, hdev, NULL, 0, NULL); | 6412 | case HCI_BREDR: |
6354 | else | 6413 | if (hci_dev_test_flag(hdev, HCI_UNCONFIGURED)) { |
6355 | mgmt_event(MGMT_EV_INDEX_ADDED, hdev, NULL, 0, NULL); | 6414 | mgmt_index_event(MGMT_EV_UNCONF_INDEX_ADDED, hdev, |
6415 | NULL, 0, HCI_MGMT_UNCONF_INDEX_EVENTS); | ||
6416 | ev.type = 0x01; | ||
6417 | } else { | ||
6418 | mgmt_index_event(MGMT_EV_INDEX_ADDED, hdev, NULL, 0, | ||
6419 | HCI_MGMT_INDEX_EVENTS); | ||
6420 | ev.type = 0x00; | ||
6421 | } | ||
6422 | break; | ||
6423 | case HCI_AMP: | ||
6424 | ev.type = 0x02; | ||
6425 | break; | ||
6426 | default: | ||
6427 | return; | ||
6428 | } | ||
6429 | |||
6430 | ev.bus = hdev->bus; | ||
6431 | |||
6432 | mgmt_index_event(MGMT_EV_EXT_INDEX_ADDED, hdev, &ev, sizeof(ev), | ||
6433 | HCI_MGMT_EXT_INDEX_EVENTS); | ||
6356 | } | 6434 | } |
6357 | 6435 | ||
6358 | void mgmt_index_removed(struct hci_dev *hdev) | 6436 | void mgmt_index_removed(struct hci_dev *hdev) |
6359 | { | 6437 | { |
6438 | struct mgmt_ev_ext_index ev; | ||
6360 | u8 status = MGMT_STATUS_INVALID_INDEX; | 6439 | u8 status = MGMT_STATUS_INVALID_INDEX; |
6361 | 6440 | ||
6362 | if (hdev->dev_type != HCI_BREDR) | 6441 | if (test_bit(HCI_QUIRK_RAW_DEVICE, &hdev->quirks)) |
6363 | return; | 6442 | return; |
6364 | 6443 | ||
6365 | if (test_bit(HCI_QUIRK_RAW_DEVICE, &hdev->quirks)) | 6444 | switch (hdev->dev_type) { |
6445 | case HCI_BREDR: | ||
6446 | mgmt_pending_foreach(0, hdev, cmd_complete_rsp, &status); | ||
6447 | |||
6448 | if (hci_dev_test_flag(hdev, HCI_UNCONFIGURED)) { | ||
6449 | mgmt_index_event(MGMT_EV_UNCONF_INDEX_REMOVED, hdev, | ||
6450 | NULL, 0, HCI_MGMT_UNCONF_INDEX_EVENTS); | ||
6451 | ev.type = 0x01; | ||
6452 | } else { | ||
6453 | mgmt_index_event(MGMT_EV_INDEX_REMOVED, hdev, NULL, 0, | ||
6454 | HCI_MGMT_INDEX_EVENTS); | ||
6455 | ev.type = 0x00; | ||
6456 | } | ||
6457 | break; | ||
6458 | case HCI_AMP: | ||
6459 | ev.type = 0x02; | ||
6460 | break; | ||
6461 | default: | ||
6366 | return; | 6462 | return; |
6463 | } | ||
6367 | 6464 | ||
6368 | mgmt_pending_foreach(0, hdev, cmd_complete_rsp, &status); | 6465 | ev.bus = hdev->bus; |
6369 | 6466 | ||
6370 | if (hci_dev_test_flag(hdev, HCI_UNCONFIGURED)) | 6467 | mgmt_index_event(MGMT_EV_EXT_INDEX_REMOVED, hdev, &ev, sizeof(ev), |
6371 | mgmt_event(MGMT_EV_UNCONF_INDEX_REMOVED, hdev, NULL, 0, NULL); | 6468 | HCI_MGMT_EXT_INDEX_EVENTS); |
6372 | else | ||
6373 | mgmt_event(MGMT_EV_INDEX_REMOVED, hdev, NULL, 0, NULL); | ||
6374 | } | 6469 | } |
6375 | 6470 | ||
6376 | /* This function requires the caller holds hdev->lock */ | 6471 | /* This function requires the caller holds hdev->lock */ |
@@ -6535,8 +6630,8 @@ int mgmt_powered(struct hci_dev *hdev, u8 powered) | |||
6535 | mgmt_pending_foreach(0, hdev, cmd_complete_rsp, &status); | 6630 | mgmt_pending_foreach(0, hdev, cmd_complete_rsp, &status); |
6536 | 6631 | ||
6537 | if (memcmp(hdev->dev_class, zero_cod, sizeof(zero_cod)) != 0) | 6632 | if (memcmp(hdev->dev_class, zero_cod, sizeof(zero_cod)) != 0) |
6538 | mgmt_event(MGMT_EV_CLASS_OF_DEV_CHANGED, hdev, | 6633 | mgmt_generic_event(MGMT_EV_CLASS_OF_DEV_CHANGED, hdev, |
6539 | zero_cod, sizeof(zero_cod), NULL); | 6634 | zero_cod, sizeof(zero_cod), NULL); |
6540 | 6635 | ||
6541 | new_settings: | 6636 | new_settings: |
6542 | err = new_settings(hdev, match.sk); | 6637 | err = new_settings(hdev, match.sk); |
@@ -6552,7 +6647,7 @@ void mgmt_set_powered_failed(struct hci_dev *hdev, int err) | |||
6552 | struct mgmt_pending_cmd *cmd; | 6647 | struct mgmt_pending_cmd *cmd; |
6553 | u8 status; | 6648 | u8 status; |
6554 | 6649 | ||
6555 | cmd = mgmt_pending_find(MGMT_OP_SET_POWERED, hdev); | 6650 | cmd = pending_find(MGMT_OP_SET_POWERED, hdev); |
6556 | if (!cmd) | 6651 | if (!cmd) |
6557 | return; | 6652 | return; |
6558 | 6653 | ||
@@ -6752,17 +6847,6 @@ void mgmt_new_conn_param(struct hci_dev *hdev, bdaddr_t *bdaddr, | |||
6752 | mgmt_event(MGMT_EV_NEW_CONN_PARAM, hdev, &ev, sizeof(ev), NULL); | 6847 | mgmt_event(MGMT_EV_NEW_CONN_PARAM, hdev, &ev, sizeof(ev), NULL); |
6753 | } | 6848 | } |
6754 | 6849 | ||
6755 | static inline u16 eir_append_data(u8 *eir, u16 eir_len, u8 type, u8 *data, | ||
6756 | u8 data_len) | ||
6757 | { | ||
6758 | eir[eir_len++] = sizeof(type) + data_len; | ||
6759 | eir[eir_len++] = type; | ||
6760 | memcpy(&eir[eir_len], data, data_len); | ||
6761 | eir_len += data_len; | ||
6762 | |||
6763 | return eir_len; | ||
6764 | } | ||
6765 | |||
6766 | void mgmt_device_connected(struct hci_dev *hdev, struct hci_conn *conn, | 6850 | void mgmt_device_connected(struct hci_dev *hdev, struct hci_conn *conn, |
6767 | u32 flags, u8 *name, u8 name_len) | 6851 | u32 flags, u8 *name, u8 name_len) |
6768 | { | 6852 | { |
@@ -6828,7 +6912,7 @@ bool mgmt_powering_down(struct hci_dev *hdev) | |||
6828 | struct mgmt_pending_cmd *cmd; | 6912 | struct mgmt_pending_cmd *cmd; |
6829 | struct mgmt_mode *cp; | 6913 | struct mgmt_mode *cp; |
6830 | 6914 | ||
6831 | cmd = mgmt_pending_find(MGMT_OP_SET_POWERED, hdev); | 6915 | cmd = pending_find(MGMT_OP_SET_POWERED, hdev); |
6832 | if (!cmd) | 6916 | if (!cmd) |
6833 | return false; | 6917 | return false; |
6834 | 6918 | ||
@@ -6885,7 +6969,7 @@ void mgmt_disconnect_failed(struct hci_dev *hdev, bdaddr_t *bdaddr, | |||
6885 | mgmt_pending_foreach(MGMT_OP_UNPAIR_DEVICE, hdev, unpair_device_rsp, | 6969 | mgmt_pending_foreach(MGMT_OP_UNPAIR_DEVICE, hdev, unpair_device_rsp, |
6886 | hdev); | 6970 | hdev); |
6887 | 6971 | ||
6888 | cmd = mgmt_pending_find(MGMT_OP_DISCONNECT, hdev); | 6972 | cmd = pending_find(MGMT_OP_DISCONNECT, hdev); |
6889 | if (!cmd) | 6973 | if (!cmd) |
6890 | return; | 6974 | return; |
6891 | 6975 | ||
@@ -6937,7 +7021,7 @@ void mgmt_pin_code_reply_complete(struct hci_dev *hdev, bdaddr_t *bdaddr, | |||
6937 | { | 7021 | { |
6938 | struct mgmt_pending_cmd *cmd; | 7022 | struct mgmt_pending_cmd *cmd; |
6939 | 7023 | ||
6940 | cmd = mgmt_pending_find(MGMT_OP_PIN_CODE_REPLY, hdev); | 7024 | cmd = pending_find(MGMT_OP_PIN_CODE_REPLY, hdev); |
6941 | if (!cmd) | 7025 | if (!cmd) |
6942 | return; | 7026 | return; |
6943 | 7027 | ||
@@ -6950,7 +7034,7 @@ void mgmt_pin_code_neg_reply_complete(struct hci_dev *hdev, bdaddr_t *bdaddr, | |||
6950 | { | 7034 | { |
6951 | struct mgmt_pending_cmd *cmd; | 7035 | struct mgmt_pending_cmd *cmd; |
6952 | 7036 | ||
6953 | cmd = mgmt_pending_find(MGMT_OP_PIN_CODE_NEG_REPLY, hdev); | 7037 | cmd = pending_find(MGMT_OP_PIN_CODE_NEG_REPLY, hdev); |
6954 | if (!cmd) | 7038 | if (!cmd) |
6955 | return; | 7039 | return; |
6956 | 7040 | ||
@@ -6995,7 +7079,7 @@ static int user_pairing_resp_complete(struct hci_dev *hdev, bdaddr_t *bdaddr, | |||
6995 | { | 7079 | { |
6996 | struct mgmt_pending_cmd *cmd; | 7080 | struct mgmt_pending_cmd *cmd; |
6997 | 7081 | ||
6998 | cmd = mgmt_pending_find(opcode, hdev); | 7082 | cmd = pending_find(opcode, hdev); |
6999 | if (!cmd) | 7083 | if (!cmd) |
7000 | return -ENOENT; | 7084 | return -ENOENT; |
7001 | 7085 | ||
@@ -7187,8 +7271,8 @@ void mgmt_set_class_of_dev_complete(struct hci_dev *hdev, u8 *dev_class, | |||
7187 | mgmt_pending_foreach(MGMT_OP_REMOVE_UUID, hdev, sk_lookup, &match); | 7271 | mgmt_pending_foreach(MGMT_OP_REMOVE_UUID, hdev, sk_lookup, &match); |
7188 | 7272 | ||
7189 | if (!status) | 7273 | if (!status) |
7190 | mgmt_event(MGMT_EV_CLASS_OF_DEV_CHANGED, hdev, dev_class, 3, | 7274 | mgmt_generic_event(MGMT_EV_CLASS_OF_DEV_CHANGED, hdev, |
7191 | NULL); | 7275 | dev_class, 3, NULL); |
7192 | 7276 | ||
7193 | if (match.sk) | 7277 | if (match.sk) |
7194 | sock_put(match.sk); | 7278 | sock_put(match.sk); |
@@ -7206,19 +7290,19 @@ void mgmt_set_local_name_complete(struct hci_dev *hdev, u8 *name, u8 status) | |||
7206 | memcpy(ev.name, name, HCI_MAX_NAME_LENGTH); | 7290 | memcpy(ev.name, name, HCI_MAX_NAME_LENGTH); |
7207 | memcpy(ev.short_name, hdev->short_name, HCI_MAX_SHORT_NAME_LENGTH); | 7291 | memcpy(ev.short_name, hdev->short_name, HCI_MAX_SHORT_NAME_LENGTH); |
7208 | 7292 | ||
7209 | cmd = mgmt_pending_find(MGMT_OP_SET_LOCAL_NAME, hdev); | 7293 | cmd = pending_find(MGMT_OP_SET_LOCAL_NAME, hdev); |
7210 | if (!cmd) { | 7294 | if (!cmd) { |
7211 | memcpy(hdev->dev_name, name, sizeof(hdev->dev_name)); | 7295 | memcpy(hdev->dev_name, name, sizeof(hdev->dev_name)); |
7212 | 7296 | ||
7213 | /* If this is a HCI command related to powering on the | 7297 | /* If this is a HCI command related to powering on the |
7214 | * HCI dev don't send any mgmt signals. | 7298 | * HCI dev don't send any mgmt signals. |
7215 | */ | 7299 | */ |
7216 | if (mgmt_pending_find(MGMT_OP_SET_POWERED, hdev)) | 7300 | if (pending_find(MGMT_OP_SET_POWERED, hdev)) |
7217 | return; | 7301 | return; |
7218 | } | 7302 | } |
7219 | 7303 | ||
7220 | mgmt_event(MGMT_EV_LOCAL_NAME_CHANGED, hdev, &ev, sizeof(ev), | 7304 | mgmt_generic_event(MGMT_EV_LOCAL_NAME_CHANGED, hdev, &ev, sizeof(ev), |
7221 | cmd ? cmd->sk : NULL); | 7305 | cmd ? cmd->sk : NULL); |
7222 | } | 7306 | } |
7223 | 7307 | ||
7224 | void mgmt_read_local_oob_data_complete(struct hci_dev *hdev, u8 *hash192, | 7308 | void mgmt_read_local_oob_data_complete(struct hci_dev *hdev, u8 *hash192, |
@@ -7229,7 +7313,7 @@ void mgmt_read_local_oob_data_complete(struct hci_dev *hdev, u8 *hash192, | |||
7229 | 7313 | ||
7230 | BT_DBG("%s status %u", hdev->name, status); | 7314 | BT_DBG("%s status %u", hdev->name, status); |
7231 | 7315 | ||
7232 | cmd = mgmt_pending_find(MGMT_OP_READ_LOCAL_OOB_DATA, hdev); | 7316 | cmd = pending_find(MGMT_OP_READ_LOCAL_OOB_DATA, hdev); |
7233 | if (!cmd) | 7317 | if (!cmd) |
7234 | return; | 7318 | return; |
7235 | 7319 | ||
@@ -7511,6 +7595,7 @@ static struct hci_mgmt_chan chan = { | |||
7511 | .channel = HCI_CHANNEL_CONTROL, | 7595 | .channel = HCI_CHANNEL_CONTROL, |
7512 | .handler_count = ARRAY_SIZE(mgmt_handlers), | 7596 | .handler_count = ARRAY_SIZE(mgmt_handlers), |
7513 | .handlers = mgmt_handlers, | 7597 | .handlers = mgmt_handlers, |
7598 | .hdev_init = mgmt_init_hdev, | ||
7514 | }; | 7599 | }; |
7515 | 7600 | ||
7516 | int mgmt_init(void) | 7601 | int mgmt_init(void) |
diff --git a/net/bluetooth/mgmt_util.c b/net/bluetooth/mgmt_util.c new file mode 100644 index 000000000000..8c30c7eb8bef --- /dev/null +++ b/net/bluetooth/mgmt_util.c | |||
@@ -0,0 +1,210 @@ | |||
1 | /* | ||
2 | BlueZ - Bluetooth protocol stack for Linux | ||
3 | |||
4 | Copyright (C) 2015 Intel Corporation | ||
5 | |||
6 | This program is free software; you can redistribute it and/or modify | ||
7 | it under the terms of the GNU General Public License version 2 as | ||
8 | published by the Free Software Foundation; | ||
9 | |||
10 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS | ||
11 | OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, | ||
12 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT OF THIRD PARTY RIGHTS. | ||
13 | IN NO EVENT SHALL THE COPYRIGHT HOLDER(S) AND AUTHOR(S) BE LIABLE FOR ANY | ||
14 | CLAIM, OR ANY SPECIAL INDIRECT OR CONSEQUENTIAL DAMAGES, OR ANY DAMAGES | ||
15 | WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN | ||
16 | ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF | ||
17 | OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. | ||
18 | |||
19 | ALL LIABILITY, INCLUDING LIABILITY FOR INFRINGEMENT OF ANY PATENTS, | ||
20 | COPYRIGHTS, TRADEMARKS OR OTHER RIGHTS, RELATING TO USE OF THIS | ||
21 | SOFTWARE IS DISCLAIMED. | ||
22 | */ | ||
23 | |||
24 | #include <net/bluetooth/bluetooth.h> | ||
25 | #include <net/bluetooth/hci_core.h> | ||
26 | #include <net/bluetooth/mgmt.h> | ||
27 | |||
28 | #include "mgmt_util.h" | ||
29 | |||
30 | int mgmt_send_event(u16 event, struct hci_dev *hdev, unsigned short channel, | ||
31 | void *data, u16 data_len, int flag, struct sock *skip_sk) | ||
32 | { | ||
33 | struct sk_buff *skb; | ||
34 | struct mgmt_hdr *hdr; | ||
35 | |||
36 | skb = alloc_skb(sizeof(*hdr) + data_len, GFP_KERNEL); | ||
37 | if (!skb) | ||
38 | return -ENOMEM; | ||
39 | |||
40 | hdr = (void *) skb_put(skb, sizeof(*hdr)); | ||
41 | hdr->opcode = cpu_to_le16(event); | ||
42 | if (hdev) | ||
43 | hdr->index = cpu_to_le16(hdev->id); | ||
44 | else | ||
45 | hdr->index = cpu_to_le16(MGMT_INDEX_NONE); | ||
46 | hdr->len = cpu_to_le16(data_len); | ||
47 | |||
48 | if (data) | ||
49 | memcpy(skb_put(skb, data_len), data, data_len); | ||
50 | |||
51 | /* Time stamp */ | ||
52 | __net_timestamp(skb); | ||
53 | |||
54 | hci_send_to_channel(channel, skb, flag, skip_sk); | ||
55 | kfree_skb(skb); | ||
56 | |||
57 | return 0; | ||
58 | } | ||
59 | |||
60 | int mgmt_cmd_status(struct sock *sk, u16 index, u16 cmd, u8 status) | ||
61 | { | ||
62 | struct sk_buff *skb; | ||
63 | struct mgmt_hdr *hdr; | ||
64 | struct mgmt_ev_cmd_status *ev; | ||
65 | int err; | ||
66 | |||
67 | BT_DBG("sock %p, index %u, cmd %u, status %u", sk, index, cmd, status); | ||
68 | |||
69 | skb = alloc_skb(sizeof(*hdr) + sizeof(*ev), GFP_KERNEL); | ||
70 | if (!skb) | ||
71 | return -ENOMEM; | ||
72 | |||
73 | hdr = (void *) skb_put(skb, sizeof(*hdr)); | ||
74 | |||
75 | hdr->opcode = cpu_to_le16(MGMT_EV_CMD_STATUS); | ||
76 | hdr->index = cpu_to_le16(index); | ||
77 | hdr->len = cpu_to_le16(sizeof(*ev)); | ||
78 | |||
79 | ev = (void *) skb_put(skb, sizeof(*ev)); | ||
80 | ev->status = status; | ||
81 | ev->opcode = cpu_to_le16(cmd); | ||
82 | |||
83 | err = sock_queue_rcv_skb(sk, skb); | ||
84 | if (err < 0) | ||
85 | kfree_skb(skb); | ||
86 | |||
87 | return err; | ||
88 | } | ||
89 | |||
90 | int mgmt_cmd_complete(struct sock *sk, u16 index, u16 cmd, u8 status, | ||
91 | void *rp, size_t rp_len) | ||
92 | { | ||
93 | struct sk_buff *skb; | ||
94 | struct mgmt_hdr *hdr; | ||
95 | struct mgmt_ev_cmd_complete *ev; | ||
96 | int err; | ||
97 | |||
98 | BT_DBG("sock %p", sk); | ||
99 | |||
100 | skb = alloc_skb(sizeof(*hdr) + sizeof(*ev) + rp_len, GFP_KERNEL); | ||
101 | if (!skb) | ||
102 | return -ENOMEM; | ||
103 | |||
104 | hdr = (void *) skb_put(skb, sizeof(*hdr)); | ||
105 | |||
106 | hdr->opcode = cpu_to_le16(MGMT_EV_CMD_COMPLETE); | ||
107 | hdr->index = cpu_to_le16(index); | ||
108 | hdr->len = cpu_to_le16(sizeof(*ev) + rp_len); | ||
109 | |||
110 | ev = (void *) skb_put(skb, sizeof(*ev) + rp_len); | ||
111 | ev->opcode = cpu_to_le16(cmd); | ||
112 | ev->status = status; | ||
113 | |||
114 | if (rp) | ||
115 | memcpy(ev->data, rp, rp_len); | ||
116 | |||
117 | err = sock_queue_rcv_skb(sk, skb); | ||
118 | if (err < 0) | ||
119 | kfree_skb(skb); | ||
120 | |||
121 | return err; | ||
122 | } | ||
123 | |||
124 | struct mgmt_pending_cmd *mgmt_pending_find(unsigned short channel, u16 opcode, | ||
125 | struct hci_dev *hdev) | ||
126 | { | ||
127 | struct mgmt_pending_cmd *cmd; | ||
128 | |||
129 | list_for_each_entry(cmd, &hdev->mgmt_pending, list) { | ||
130 | if (hci_sock_get_channel(cmd->sk) != channel) | ||
131 | continue; | ||
132 | if (cmd->opcode == opcode) | ||
133 | return cmd; | ||
134 | } | ||
135 | |||
136 | return NULL; | ||
137 | } | ||
138 | |||
139 | struct mgmt_pending_cmd *mgmt_pending_find_data(unsigned short channel, | ||
140 | u16 opcode, | ||
141 | struct hci_dev *hdev, | ||
142 | const void *data) | ||
143 | { | ||
144 | struct mgmt_pending_cmd *cmd; | ||
145 | |||
146 | list_for_each_entry(cmd, &hdev->mgmt_pending, list) { | ||
147 | if (cmd->user_data != data) | ||
148 | continue; | ||
149 | if (cmd->opcode == opcode) | ||
150 | return cmd; | ||
151 | } | ||
152 | |||
153 | return NULL; | ||
154 | } | ||
155 | |||
156 | void mgmt_pending_foreach(u16 opcode, struct hci_dev *hdev, | ||
157 | void (*cb)(struct mgmt_pending_cmd *cmd, void *data), | ||
158 | void *data) | ||
159 | { | ||
160 | struct mgmt_pending_cmd *cmd, *tmp; | ||
161 | |||
162 | list_for_each_entry_safe(cmd, tmp, &hdev->mgmt_pending, list) { | ||
163 | if (opcode > 0 && cmd->opcode != opcode) | ||
164 | continue; | ||
165 | |||
166 | cb(cmd, data); | ||
167 | } | ||
168 | } | ||
169 | |||
170 | struct mgmt_pending_cmd *mgmt_pending_add(struct sock *sk, u16 opcode, | ||
171 | struct hci_dev *hdev, | ||
172 | void *data, u16 len) | ||
173 | { | ||
174 | struct mgmt_pending_cmd *cmd; | ||
175 | |||
176 | cmd = kzalloc(sizeof(*cmd), GFP_KERNEL); | ||
177 | if (!cmd) | ||
178 | return NULL; | ||
179 | |||
180 | cmd->opcode = opcode; | ||
181 | cmd->index = hdev->id; | ||
182 | |||
183 | cmd->param = kmemdup(data, len, GFP_KERNEL); | ||
184 | if (!cmd->param) { | ||
185 | kfree(cmd); | ||
186 | return NULL; | ||
187 | } | ||
188 | |||
189 | cmd->param_len = len; | ||
190 | |||
191 | cmd->sk = sk; | ||
192 | sock_hold(sk); | ||
193 | |||
194 | list_add(&cmd->list, &hdev->mgmt_pending); | ||
195 | |||
196 | return cmd; | ||
197 | } | ||
198 | |||
199 | void mgmt_pending_free(struct mgmt_pending_cmd *cmd) | ||
200 | { | ||
201 | sock_put(cmd->sk); | ||
202 | kfree(cmd->param); | ||
203 | kfree(cmd); | ||
204 | } | ||
205 | |||
206 | void mgmt_pending_remove(struct mgmt_pending_cmd *cmd) | ||
207 | { | ||
208 | list_del(&cmd->list); | ||
209 | mgmt_pending_free(cmd); | ||
210 | } | ||
diff --git a/net/bluetooth/mgmt_util.h b/net/bluetooth/mgmt_util.h new file mode 100644 index 000000000000..6559f189213c --- /dev/null +++ b/net/bluetooth/mgmt_util.h | |||
@@ -0,0 +1,53 @@ | |||
1 | /* | ||
2 | BlueZ - Bluetooth protocol stack for Linux | ||
3 | Copyright (C) 2015 Intel Coropration | ||
4 | |||
5 | This program is free software; you can redistribute it and/or modify | ||
6 | it under the terms of the GNU General Public License version 2 as | ||
7 | published by the Free Software Foundation; | ||
8 | |||
9 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS | ||
10 | OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, | ||
11 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT OF THIRD PARTY RIGHTS. | ||
12 | IN NO EVENT SHALL THE COPYRIGHT HOLDER(S) AND AUTHOR(S) BE LIABLE FOR ANY | ||
13 | CLAIM, OR ANY SPECIAL INDIRECT OR CONSEQUENTIAL DAMAGES, OR ANY DAMAGES | ||
14 | WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN | ||
15 | ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF | ||
16 | OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. | ||
17 | |||
18 | ALL LIABILITY, INCLUDING LIABILITY FOR INFRINGEMENT OF ANY PATENTS, | ||
19 | COPYRIGHTS, TRADEMARKS OR OTHER RIGHTS, RELATING TO USE OF THIS | ||
20 | SOFTWARE IS DISCLAIMED. | ||
21 | */ | ||
22 | |||
23 | struct mgmt_pending_cmd { | ||
24 | struct list_head list; | ||
25 | u16 opcode; | ||
26 | int index; | ||
27 | void *param; | ||
28 | size_t param_len; | ||
29 | struct sock *sk; | ||
30 | void *user_data; | ||
31 | int (*cmd_complete)(struct mgmt_pending_cmd *cmd, u8 status); | ||
32 | }; | ||
33 | |||
34 | int mgmt_send_event(u16 event, struct hci_dev *hdev, unsigned short channel, | ||
35 | void *data, u16 data_len, int flag, struct sock *skip_sk); | ||
36 | int mgmt_cmd_status(struct sock *sk, u16 index, u16 cmd, u8 status); | ||
37 | int mgmt_cmd_complete(struct sock *sk, u16 index, u16 cmd, u8 status, | ||
38 | void *rp, size_t rp_len); | ||
39 | |||
40 | struct mgmt_pending_cmd *mgmt_pending_find(unsigned short channel, u16 opcode, | ||
41 | struct hci_dev *hdev); | ||
42 | struct mgmt_pending_cmd *mgmt_pending_find_data(unsigned short channel, | ||
43 | u16 opcode, | ||
44 | struct hci_dev *hdev, | ||
45 | const void *data); | ||
46 | void mgmt_pending_foreach(u16 opcode, struct hci_dev *hdev, | ||
47 | void (*cb)(struct mgmt_pending_cmd *cmd, void *data), | ||
48 | void *data); | ||
49 | struct mgmt_pending_cmd *mgmt_pending_add(struct sock *sk, u16 opcode, | ||
50 | struct hci_dev *hdev, | ||
51 | void *data, u16 len); | ||
52 | void mgmt_pending_free(struct mgmt_pending_cmd *cmd); | ||
53 | void mgmt_pending_remove(struct mgmt_pending_cmd *cmd); | ||
diff --git a/net/bluetooth/smp.c b/net/bluetooth/smp.c index 9155840068cf..1ec3f66b5a74 100644 --- a/net/bluetooth/smp.c +++ b/net/bluetooth/smp.c | |||
@@ -70,7 +70,19 @@ enum { | |||
70 | SMP_FLAG_DEBUG_KEY, | 70 | SMP_FLAG_DEBUG_KEY, |
71 | SMP_FLAG_WAIT_USER, | 71 | SMP_FLAG_WAIT_USER, |
72 | SMP_FLAG_DHKEY_PENDING, | 72 | SMP_FLAG_DHKEY_PENDING, |
73 | SMP_FLAG_OOB, | 73 | SMP_FLAG_REMOTE_OOB, |
74 | SMP_FLAG_LOCAL_OOB, | ||
75 | }; | ||
76 | |||
77 | struct smp_dev { | ||
78 | /* Secure Connections OOB data */ | ||
79 | u8 local_pk[64]; | ||
80 | u8 local_sk[32]; | ||
81 | u8 local_rand[16]; | ||
82 | bool debug_key; | ||
83 | |||
84 | struct crypto_blkcipher *tfm_aes; | ||
85 | struct crypto_hash *tfm_cmac; | ||
74 | }; | 86 | }; |
75 | 87 | ||
76 | struct smp_chan { | 88 | struct smp_chan { |
@@ -84,7 +96,8 @@ struct smp_chan { | |||
84 | u8 rrnd[16]; /* SMP Pairing Random (remote) */ | 96 | u8 rrnd[16]; /* SMP Pairing Random (remote) */ |
85 | u8 pcnf[16]; /* SMP Pairing Confirm */ | 97 | u8 pcnf[16]; /* SMP Pairing Confirm */ |
86 | u8 tk[16]; /* SMP Temporary Key */ | 98 | u8 tk[16]; /* SMP Temporary Key */ |
87 | u8 rr[16]; | 99 | u8 rr[16]; /* Remote OOB ra/rb value */ |
100 | u8 lr[16]; /* Local OOB ra/rb value */ | ||
88 | u8 enc_key_size; | 101 | u8 enc_key_size; |
89 | u8 remote_key_dist; | 102 | u8 remote_key_dist; |
90 | bdaddr_t id_addr; | 103 | bdaddr_t id_addr; |
@@ -478,18 +491,18 @@ bool smp_irk_matches(struct hci_dev *hdev, const u8 irk[16], | |||
478 | const bdaddr_t *bdaddr) | 491 | const bdaddr_t *bdaddr) |
479 | { | 492 | { |
480 | struct l2cap_chan *chan = hdev->smp_data; | 493 | struct l2cap_chan *chan = hdev->smp_data; |
481 | struct crypto_blkcipher *tfm; | 494 | struct smp_dev *smp; |
482 | u8 hash[3]; | 495 | u8 hash[3]; |
483 | int err; | 496 | int err; |
484 | 497 | ||
485 | if (!chan || !chan->data) | 498 | if (!chan || !chan->data) |
486 | return false; | 499 | return false; |
487 | 500 | ||
488 | tfm = chan->data; | 501 | smp = chan->data; |
489 | 502 | ||
490 | BT_DBG("RPA %pMR IRK %*phN", bdaddr, 16, irk); | 503 | BT_DBG("RPA %pMR IRK %*phN", bdaddr, 16, irk); |
491 | 504 | ||
492 | err = smp_ah(tfm, irk, &bdaddr->b[3], hash); | 505 | err = smp_ah(smp->tfm_aes, irk, &bdaddr->b[3], hash); |
493 | if (err) | 506 | if (err) |
494 | return false; | 507 | return false; |
495 | 508 | ||
@@ -499,20 +512,20 @@ bool smp_irk_matches(struct hci_dev *hdev, const u8 irk[16], | |||
499 | int smp_generate_rpa(struct hci_dev *hdev, const u8 irk[16], bdaddr_t *rpa) | 512 | int smp_generate_rpa(struct hci_dev *hdev, const u8 irk[16], bdaddr_t *rpa) |
500 | { | 513 | { |
501 | struct l2cap_chan *chan = hdev->smp_data; | 514 | struct l2cap_chan *chan = hdev->smp_data; |
502 | struct crypto_blkcipher *tfm; | 515 | struct smp_dev *smp; |
503 | int err; | 516 | int err; |
504 | 517 | ||
505 | if (!chan || !chan->data) | 518 | if (!chan || !chan->data) |
506 | return -EOPNOTSUPP; | 519 | return -EOPNOTSUPP; |
507 | 520 | ||
508 | tfm = chan->data; | 521 | smp = chan->data; |
509 | 522 | ||
510 | get_random_bytes(&rpa->b[3], 3); | 523 | get_random_bytes(&rpa->b[3], 3); |
511 | 524 | ||
512 | rpa->b[5] &= 0x3f; /* Clear two most significant bits */ | 525 | rpa->b[5] &= 0x3f; /* Clear two most significant bits */ |
513 | rpa->b[5] |= 0x40; /* Set second most significant bit */ | 526 | rpa->b[5] |= 0x40; /* Set second most significant bit */ |
514 | 527 | ||
515 | err = smp_ah(tfm, irk, &rpa->b[3], rpa->b); | 528 | err = smp_ah(smp->tfm_aes, irk, &rpa->b[3], rpa->b); |
516 | if (err < 0) | 529 | if (err < 0) |
517 | return err; | 530 | return err; |
518 | 531 | ||
@@ -521,6 +534,53 @@ int smp_generate_rpa(struct hci_dev *hdev, const u8 irk[16], bdaddr_t *rpa) | |||
521 | return 0; | 534 | return 0; |
522 | } | 535 | } |
523 | 536 | ||
537 | int smp_generate_oob(struct hci_dev *hdev, u8 hash[16], u8 rand[16]) | ||
538 | { | ||
539 | struct l2cap_chan *chan = hdev->smp_data; | ||
540 | struct smp_dev *smp; | ||
541 | int err; | ||
542 | |||
543 | if (!chan || !chan->data) | ||
544 | return -EOPNOTSUPP; | ||
545 | |||
546 | smp = chan->data; | ||
547 | |||
548 | if (hci_dev_test_flag(hdev, HCI_USE_DEBUG_KEYS)) { | ||
549 | BT_DBG("Using debug keys"); | ||
550 | memcpy(smp->local_pk, debug_pk, 64); | ||
551 | memcpy(smp->local_sk, debug_sk, 32); | ||
552 | smp->debug_key = true; | ||
553 | } else { | ||
554 | while (true) { | ||
555 | /* Generate local key pair for Secure Connections */ | ||
556 | if (!ecc_make_key(smp->local_pk, smp->local_sk)) | ||
557 | return -EIO; | ||
558 | |||
559 | /* This is unlikely, but we need to check that | ||
560 | * we didn't accidentially generate a debug key. | ||
561 | */ | ||
562 | if (memcmp(smp->local_sk, debug_sk, 32)) | ||
563 | break; | ||
564 | } | ||
565 | smp->debug_key = false; | ||
566 | } | ||
567 | |||
568 | SMP_DBG("OOB Public Key X: %32phN", smp->local_pk); | ||
569 | SMP_DBG("OOB Public Key Y: %32phN", smp->local_pk + 32); | ||
570 | SMP_DBG("OOB Private Key: %32phN", smp->local_sk); | ||
571 | |||
572 | get_random_bytes(smp->local_rand, 16); | ||
573 | |||
574 | err = smp_f4(smp->tfm_cmac, smp->local_pk, smp->local_pk, | ||
575 | smp->local_rand, 0, hash); | ||
576 | if (err < 0) | ||
577 | return err; | ||
578 | |||
579 | memcpy(rand, smp->local_rand, 16); | ||
580 | |||
581 | return 0; | ||
582 | } | ||
583 | |||
524 | static void smp_send_cmd(struct l2cap_conn *conn, u8 code, u16 len, void *data) | 584 | static void smp_send_cmd(struct l2cap_conn *conn, u8 code, u16 len, void *data) |
525 | { | 585 | { |
526 | struct l2cap_chan *chan = conn->smp; | 586 | struct l2cap_chan *chan = conn->smp; |
@@ -621,10 +681,12 @@ static void build_pairing_cmd(struct l2cap_conn *conn, | |||
621 | oob_data = hci_find_remote_oob_data(hdev, &hcon->dst, | 681 | oob_data = hci_find_remote_oob_data(hdev, &hcon->dst, |
622 | bdaddr_type); | 682 | bdaddr_type); |
623 | if (oob_data && oob_data->present) { | 683 | if (oob_data && oob_data->present) { |
624 | set_bit(SMP_FLAG_OOB, &smp->flags); | 684 | set_bit(SMP_FLAG_REMOTE_OOB, &smp->flags); |
625 | oob_flag = SMP_OOB_PRESENT; | 685 | oob_flag = SMP_OOB_PRESENT; |
626 | memcpy(smp->rr, oob_data->rand256, 16); | 686 | memcpy(smp->rr, oob_data->rand256, 16); |
627 | memcpy(smp->pcnf, oob_data->hash256, 16); | 687 | memcpy(smp->pcnf, oob_data->hash256, 16); |
688 | SMP_DBG("OOB Remote Confirmation: %16phN", smp->pcnf); | ||
689 | SMP_DBG("OOB Remote Random: %16phN", smp->rr); | ||
628 | } | 690 | } |
629 | 691 | ||
630 | } else { | 692 | } else { |
@@ -681,9 +743,9 @@ static void smp_chan_destroy(struct l2cap_conn *conn) | |||
681 | complete = test_bit(SMP_FLAG_COMPLETE, &smp->flags); | 743 | complete = test_bit(SMP_FLAG_COMPLETE, &smp->flags); |
682 | mgmt_smp_complete(hcon, complete); | 744 | mgmt_smp_complete(hcon, complete); |
683 | 745 | ||
684 | kfree(smp->csrk); | 746 | kzfree(smp->csrk); |
685 | kfree(smp->slave_csrk); | 747 | kzfree(smp->slave_csrk); |
686 | kfree(smp->link_key); | 748 | kzfree(smp->link_key); |
687 | 749 | ||
688 | crypto_free_blkcipher(smp->tfm_aes); | 750 | crypto_free_blkcipher(smp->tfm_aes); |
689 | crypto_free_hash(smp->tfm_cmac); | 751 | crypto_free_hash(smp->tfm_cmac); |
@@ -717,7 +779,7 @@ static void smp_chan_destroy(struct l2cap_conn *conn) | |||
717 | } | 779 | } |
718 | 780 | ||
719 | chan->data = NULL; | 781 | chan->data = NULL; |
720 | kfree(smp); | 782 | kzfree(smp); |
721 | hci_conn_drop(hcon); | 783 | hci_conn_drop(hcon); |
722 | } | 784 | } |
723 | 785 | ||
@@ -818,6 +880,12 @@ static int tk_request(struct l2cap_conn *conn, u8 remote_oob, u8 auth, | |||
818 | return 0; | 880 | return 0; |
819 | } | 881 | } |
820 | 882 | ||
883 | /* If this function is used for SC -> legacy fallback we | ||
884 | * can only recover the just-works case. | ||
885 | */ | ||
886 | if (test_bit(SMP_FLAG_SC, &smp->flags)) | ||
887 | return -EINVAL; | ||
888 | |||
821 | /* Not Just Works/Confirm results in MITM Authentication */ | 889 | /* Not Just Works/Confirm results in MITM Authentication */ |
822 | if (smp->method != JUST_CFM) { | 890 | if (smp->method != JUST_CFM) { |
823 | set_bit(SMP_FLAG_MITM_AUTH, &smp->flags); | 891 | set_bit(SMP_FLAG_MITM_AUTH, &smp->flags); |
@@ -1097,13 +1165,13 @@ static void sc_generate_link_key(struct smp_chan *smp) | |||
1097 | return; | 1165 | return; |
1098 | 1166 | ||
1099 | if (smp_h6(smp->tfm_cmac, smp->tk, tmp1, smp->link_key)) { | 1167 | if (smp_h6(smp->tfm_cmac, smp->tk, tmp1, smp->link_key)) { |
1100 | kfree(smp->link_key); | 1168 | kzfree(smp->link_key); |
1101 | smp->link_key = NULL; | 1169 | smp->link_key = NULL; |
1102 | return; | 1170 | return; |
1103 | } | 1171 | } |
1104 | 1172 | ||
1105 | if (smp_h6(smp->tfm_cmac, smp->link_key, lebr, smp->link_key)) { | 1173 | if (smp_h6(smp->tfm_cmac, smp->link_key, lebr, smp->link_key)) { |
1106 | kfree(smp->link_key); | 1174 | kzfree(smp->link_key); |
1107 | smp->link_key = NULL; | 1175 | smp->link_key = NULL; |
1108 | return; | 1176 | return; |
1109 | } | 1177 | } |
@@ -1300,7 +1368,7 @@ static struct smp_chan *smp_chan_create(struct l2cap_conn *conn) | |||
1300 | smp->tfm_aes = crypto_alloc_blkcipher("ecb(aes)", 0, CRYPTO_ALG_ASYNC); | 1368 | smp->tfm_aes = crypto_alloc_blkcipher("ecb(aes)", 0, CRYPTO_ALG_ASYNC); |
1301 | if (IS_ERR(smp->tfm_aes)) { | 1369 | if (IS_ERR(smp->tfm_aes)) { |
1302 | BT_ERR("Unable to create ECB crypto context"); | 1370 | BT_ERR("Unable to create ECB crypto context"); |
1303 | kfree(smp); | 1371 | kzfree(smp); |
1304 | return NULL; | 1372 | return NULL; |
1305 | } | 1373 | } |
1306 | 1374 | ||
@@ -1308,7 +1376,7 @@ static struct smp_chan *smp_chan_create(struct l2cap_conn *conn) | |||
1308 | if (IS_ERR(smp->tfm_cmac)) { | 1376 | if (IS_ERR(smp->tfm_cmac)) { |
1309 | BT_ERR("Unable to create CMAC crypto context"); | 1377 | BT_ERR("Unable to create CMAC crypto context"); |
1310 | crypto_free_blkcipher(smp->tfm_aes); | 1378 | crypto_free_blkcipher(smp->tfm_aes); |
1311 | kfree(smp); | 1379 | kzfree(smp); |
1312 | return NULL; | 1380 | return NULL; |
1313 | } | 1381 | } |
1314 | 1382 | ||
@@ -1675,6 +1743,13 @@ static u8 smp_cmd_pairing_req(struct l2cap_conn *conn, struct sk_buff *skb) | |||
1675 | memcpy(&smp->preq[1], req, sizeof(*req)); | 1743 | memcpy(&smp->preq[1], req, sizeof(*req)); |
1676 | skb_pull(skb, sizeof(*req)); | 1744 | skb_pull(skb, sizeof(*req)); |
1677 | 1745 | ||
1746 | /* If the remote side's OOB flag is set it means it has | ||
1747 | * successfully received our local OOB data - therefore set the | ||
1748 | * flag to indicate that local OOB is in use. | ||
1749 | */ | ||
1750 | if (req->oob_flag == SMP_OOB_PRESENT) | ||
1751 | set_bit(SMP_FLAG_LOCAL_OOB, &smp->flags); | ||
1752 | |||
1678 | /* SMP over BR/EDR requires special treatment */ | 1753 | /* SMP over BR/EDR requires special treatment */ |
1679 | if (conn->hcon->type == ACL_LINK) { | 1754 | if (conn->hcon->type == ACL_LINK) { |
1680 | /* We must have a BR/EDR SC link */ | 1755 | /* We must have a BR/EDR SC link */ |
@@ -1737,6 +1812,13 @@ static u8 smp_cmd_pairing_req(struct l2cap_conn *conn, struct sk_buff *skb) | |||
1737 | 1812 | ||
1738 | clear_bit(SMP_FLAG_INITIATOR, &smp->flags); | 1813 | clear_bit(SMP_FLAG_INITIATOR, &smp->flags); |
1739 | 1814 | ||
1815 | /* Strictly speaking we shouldn't allow Pairing Confirm for the | ||
1816 | * SC case, however some implementations incorrectly copy RFU auth | ||
1817 | * req bits from our security request, which may create a false | ||
1818 | * positive SC enablement. | ||
1819 | */ | ||
1820 | SMP_ALLOW_CMD(smp, SMP_CMD_PAIRING_CONFIRM); | ||
1821 | |||
1740 | if (test_bit(SMP_FLAG_SC, &smp->flags)) { | 1822 | if (test_bit(SMP_FLAG_SC, &smp->flags)) { |
1741 | SMP_ALLOW_CMD(smp, SMP_CMD_PUBLIC_KEY); | 1823 | SMP_ALLOW_CMD(smp, SMP_CMD_PUBLIC_KEY); |
1742 | /* Clear bits which are generated but not distributed */ | 1824 | /* Clear bits which are generated but not distributed */ |
@@ -1745,8 +1827,6 @@ static u8 smp_cmd_pairing_req(struct l2cap_conn *conn, struct sk_buff *skb) | |||
1745 | return 0; | 1827 | return 0; |
1746 | } | 1828 | } |
1747 | 1829 | ||
1748 | SMP_ALLOW_CMD(smp, SMP_CMD_PAIRING_CONFIRM); | ||
1749 | |||
1750 | /* Request setup of TK */ | 1830 | /* Request setup of TK */ |
1751 | ret = tk_request(conn, 0, auth, rsp.io_capability, req->io_capability); | 1831 | ret = tk_request(conn, 0, auth, rsp.io_capability, req->io_capability); |
1752 | if (ret) | 1832 | if (ret) |
@@ -1761,6 +1841,25 @@ static u8 sc_send_public_key(struct smp_chan *smp) | |||
1761 | 1841 | ||
1762 | BT_DBG(""); | 1842 | BT_DBG(""); |
1763 | 1843 | ||
1844 | if (test_bit(SMP_FLAG_LOCAL_OOB, &smp->flags)) { | ||
1845 | struct l2cap_chan *chan = hdev->smp_data; | ||
1846 | struct smp_dev *smp_dev; | ||
1847 | |||
1848 | if (!chan || !chan->data) | ||
1849 | return SMP_UNSPECIFIED; | ||
1850 | |||
1851 | smp_dev = chan->data; | ||
1852 | |||
1853 | memcpy(smp->local_pk, smp_dev->local_pk, 64); | ||
1854 | memcpy(smp->local_sk, smp_dev->local_sk, 32); | ||
1855 | memcpy(smp->lr, smp_dev->local_rand, 16); | ||
1856 | |||
1857 | if (smp_dev->debug_key) | ||
1858 | set_bit(SMP_FLAG_DEBUG_KEY, &smp->flags); | ||
1859 | |||
1860 | goto done; | ||
1861 | } | ||
1862 | |||
1764 | if (hci_dev_test_flag(hdev, HCI_USE_DEBUG_KEYS)) { | 1863 | if (hci_dev_test_flag(hdev, HCI_USE_DEBUG_KEYS)) { |
1765 | BT_DBG("Using debug keys"); | 1864 | BT_DBG("Using debug keys"); |
1766 | memcpy(smp->local_pk, debug_pk, 64); | 1865 | memcpy(smp->local_pk, debug_pk, 64); |
@@ -1780,8 +1879,9 @@ static u8 sc_send_public_key(struct smp_chan *smp) | |||
1780 | } | 1879 | } |
1781 | } | 1880 | } |
1782 | 1881 | ||
1882 | done: | ||
1783 | SMP_DBG("Local Public Key X: %32phN", smp->local_pk); | 1883 | SMP_DBG("Local Public Key X: %32phN", smp->local_pk); |
1784 | SMP_DBG("Local Public Key Y: %32phN", &smp->local_pk[32]); | 1884 | SMP_DBG("Local Public Key Y: %32phN", smp->local_pk + 32); |
1785 | SMP_DBG("Local Private Key: %32phN", smp->local_sk); | 1885 | SMP_DBG("Local Private Key: %32phN", smp->local_sk); |
1786 | 1886 | ||
1787 | smp_send_cmd(smp->conn, SMP_CMD_PUBLIC_KEY, 64, smp->local_pk); | 1887 | smp_send_cmd(smp->conn, SMP_CMD_PUBLIC_KEY, 64, smp->local_pk); |
@@ -1819,6 +1919,13 @@ static u8 smp_cmd_pairing_rsp(struct l2cap_conn *conn, struct sk_buff *skb) | |||
1819 | if (hci_dev_test_flag(hdev, HCI_SC_ONLY) && !(auth & SMP_AUTH_SC)) | 1919 | if (hci_dev_test_flag(hdev, HCI_SC_ONLY) && !(auth & SMP_AUTH_SC)) |
1820 | return SMP_AUTH_REQUIREMENTS; | 1920 | return SMP_AUTH_REQUIREMENTS; |
1821 | 1921 | ||
1922 | /* If the remote side's OOB flag is set it means it has | ||
1923 | * successfully received our local OOB data - therefore set the | ||
1924 | * flag to indicate that local OOB is in use. | ||
1925 | */ | ||
1926 | if (rsp->oob_flag == SMP_OOB_PRESENT) | ||
1927 | set_bit(SMP_FLAG_LOCAL_OOB, &smp->flags); | ||
1928 | |||
1822 | smp->prsp[0] = SMP_CMD_PAIRING_RSP; | 1929 | smp->prsp[0] = SMP_CMD_PAIRING_RSP; |
1823 | memcpy(&smp->prsp[1], rsp, sizeof(*rsp)); | 1930 | memcpy(&smp->prsp[1], rsp, sizeof(*rsp)); |
1824 | 1931 | ||
@@ -1885,10 +1992,6 @@ static u8 sc_check_confirm(struct smp_chan *smp) | |||
1885 | 1992 | ||
1886 | BT_DBG(""); | 1993 | BT_DBG(""); |
1887 | 1994 | ||
1888 | /* Public Key exchange must happen before any other steps */ | ||
1889 | if (!test_bit(SMP_FLAG_REMOTE_PK, &smp->flags)) | ||
1890 | return SMP_UNSPECIFIED; | ||
1891 | |||
1892 | if (smp->method == REQ_PASSKEY || smp->method == DSP_PASSKEY) | 1995 | if (smp->method == REQ_PASSKEY || smp->method == DSP_PASSKEY) |
1893 | return sc_passkey_round(smp, SMP_CMD_PAIRING_CONFIRM); | 1996 | return sc_passkey_round(smp, SMP_CMD_PAIRING_CONFIRM); |
1894 | 1997 | ||
@@ -1901,6 +2004,47 @@ static u8 sc_check_confirm(struct smp_chan *smp) | |||
1901 | return 0; | 2004 | return 0; |
1902 | } | 2005 | } |
1903 | 2006 | ||
2007 | /* Work-around for some implementations that incorrectly copy RFU bits | ||
2008 | * from our security request and thereby create the impression that | ||
2009 | * we're doing SC when in fact the remote doesn't support it. | ||
2010 | */ | ||
2011 | static int fixup_sc_false_positive(struct smp_chan *smp) | ||
2012 | { | ||
2013 | struct l2cap_conn *conn = smp->conn; | ||
2014 | struct hci_conn *hcon = conn->hcon; | ||
2015 | struct hci_dev *hdev = hcon->hdev; | ||
2016 | struct smp_cmd_pairing *req, *rsp; | ||
2017 | u8 auth; | ||
2018 | |||
2019 | /* The issue is only observed when we're in slave role */ | ||
2020 | if (hcon->out) | ||
2021 | return SMP_UNSPECIFIED; | ||
2022 | |||
2023 | if (hci_dev_test_flag(hdev, HCI_SC_ONLY)) { | ||
2024 | BT_ERR("Refusing SMP SC -> legacy fallback in SC-only mode"); | ||
2025 | return SMP_UNSPECIFIED; | ||
2026 | } | ||
2027 | |||
2028 | BT_ERR("Trying to fall back to legacy SMP"); | ||
2029 | |||
2030 | req = (void *) &smp->preq[1]; | ||
2031 | rsp = (void *) &smp->prsp[1]; | ||
2032 | |||
2033 | /* Rebuild key dist flags which may have been cleared for SC */ | ||
2034 | smp->remote_key_dist = (req->init_key_dist & rsp->resp_key_dist); | ||
2035 | |||
2036 | auth = req->auth_req & AUTH_REQ_MASK(hdev); | ||
2037 | |||
2038 | if (tk_request(conn, 0, auth, rsp->io_capability, req->io_capability)) { | ||
2039 | BT_ERR("Failed to fall back to legacy SMP"); | ||
2040 | return SMP_UNSPECIFIED; | ||
2041 | } | ||
2042 | |||
2043 | clear_bit(SMP_FLAG_SC, &smp->flags); | ||
2044 | |||
2045 | return 0; | ||
2046 | } | ||
2047 | |||
1904 | static u8 smp_cmd_pairing_confirm(struct l2cap_conn *conn, struct sk_buff *skb) | 2048 | static u8 smp_cmd_pairing_confirm(struct l2cap_conn *conn, struct sk_buff *skb) |
1905 | { | 2049 | { |
1906 | struct l2cap_chan *chan = conn->smp; | 2050 | struct l2cap_chan *chan = conn->smp; |
@@ -1914,8 +2058,19 @@ static u8 smp_cmd_pairing_confirm(struct l2cap_conn *conn, struct sk_buff *skb) | |||
1914 | memcpy(smp->pcnf, skb->data, sizeof(smp->pcnf)); | 2058 | memcpy(smp->pcnf, skb->data, sizeof(smp->pcnf)); |
1915 | skb_pull(skb, sizeof(smp->pcnf)); | 2059 | skb_pull(skb, sizeof(smp->pcnf)); |
1916 | 2060 | ||
1917 | if (test_bit(SMP_FLAG_SC, &smp->flags)) | 2061 | if (test_bit(SMP_FLAG_SC, &smp->flags)) { |
1918 | return sc_check_confirm(smp); | 2062 | int ret; |
2063 | |||
2064 | /* Public Key exchange must happen before any other steps */ | ||
2065 | if (test_bit(SMP_FLAG_REMOTE_PK, &smp->flags)) | ||
2066 | return sc_check_confirm(smp); | ||
2067 | |||
2068 | BT_ERR("Unexpected SMP Pairing Confirm"); | ||
2069 | |||
2070 | ret = fixup_sc_false_positive(smp); | ||
2071 | if (ret) | ||
2072 | return ret; | ||
2073 | } | ||
1919 | 2074 | ||
1920 | if (conn->hcon->out) { | 2075 | if (conn->hcon->out) { |
1921 | smp_send_cmd(conn, SMP_CMD_PAIRING_RANDOM, sizeof(smp->prnd), | 2076 | smp_send_cmd(conn, SMP_CMD_PAIRING_RANDOM, sizeof(smp->prnd), |
@@ -2374,7 +2529,8 @@ static u8 sc_select_method(struct smp_chan *smp) | |||
2374 | struct smp_cmd_pairing *local, *remote; | 2529 | struct smp_cmd_pairing *local, *remote; |
2375 | u8 local_mitm, remote_mitm, local_io, remote_io, method; | 2530 | u8 local_mitm, remote_mitm, local_io, remote_io, method; |
2376 | 2531 | ||
2377 | if (test_bit(SMP_FLAG_OOB, &smp->flags)) | 2532 | if (test_bit(SMP_FLAG_REMOTE_OOB, &smp->flags) || |
2533 | test_bit(SMP_FLAG_LOCAL_OOB, &smp->flags)) | ||
2378 | return REQ_OOB; | 2534 | return REQ_OOB; |
2379 | 2535 | ||
2380 | /* The preq/prsp contain the raw Pairing Request/Response PDUs | 2536 | /* The preq/prsp contain the raw Pairing Request/Response PDUs |
@@ -2428,6 +2584,16 @@ static int smp_cmd_public_key(struct l2cap_conn *conn, struct sk_buff *skb) | |||
2428 | 2584 | ||
2429 | memcpy(smp->remote_pk, key, 64); | 2585 | memcpy(smp->remote_pk, key, 64); |
2430 | 2586 | ||
2587 | if (test_bit(SMP_FLAG_REMOTE_OOB, &smp->flags)) { | ||
2588 | err = smp_f4(smp->tfm_cmac, smp->remote_pk, smp->remote_pk, | ||
2589 | smp->rr, 0, cfm.confirm_val); | ||
2590 | if (err) | ||
2591 | return SMP_UNSPECIFIED; | ||
2592 | |||
2593 | if (memcmp(cfm.confirm_val, smp->pcnf, 16)) | ||
2594 | return SMP_CONFIRM_FAILED; | ||
2595 | } | ||
2596 | |||
2431 | /* Non-initiating device sends its public key after receiving | 2597 | /* Non-initiating device sends its public key after receiving |
2432 | * the key from the initiating device. | 2598 | * the key from the initiating device. |
2433 | */ | 2599 | */ |
@@ -2438,7 +2604,7 @@ static int smp_cmd_public_key(struct l2cap_conn *conn, struct sk_buff *skb) | |||
2438 | } | 2604 | } |
2439 | 2605 | ||
2440 | SMP_DBG("Remote Public Key X: %32phN", smp->remote_pk); | 2606 | SMP_DBG("Remote Public Key X: %32phN", smp->remote_pk); |
2441 | SMP_DBG("Remote Public Key Y: %32phN", &smp->remote_pk[32]); | 2607 | SMP_DBG("Remote Public Key Y: %32phN", smp->remote_pk + 32); |
2442 | 2608 | ||
2443 | if (!ecdh_shared_secret(smp->remote_pk, smp->local_sk, smp->dhkey)) | 2609 | if (!ecdh_shared_secret(smp->remote_pk, smp->local_sk, smp->dhkey)) |
2444 | return SMP_UNSPECIFIED; | 2610 | return SMP_UNSPECIFIED; |
@@ -2476,14 +2642,6 @@ static int smp_cmd_public_key(struct l2cap_conn *conn, struct sk_buff *skb) | |||
2476 | } | 2642 | } |
2477 | 2643 | ||
2478 | if (smp->method == REQ_OOB) { | 2644 | if (smp->method == REQ_OOB) { |
2479 | err = smp_f4(smp->tfm_cmac, smp->remote_pk, smp->remote_pk, | ||
2480 | smp->rr, 0, cfm.confirm_val); | ||
2481 | if (err) | ||
2482 | return SMP_UNSPECIFIED; | ||
2483 | |||
2484 | if (memcmp(cfm.confirm_val, smp->pcnf, 16)) | ||
2485 | return SMP_CONFIRM_FAILED; | ||
2486 | |||
2487 | if (hcon->out) | 2645 | if (hcon->out) |
2488 | smp_send_cmd(conn, SMP_CMD_PAIRING_RANDOM, | 2646 | smp_send_cmd(conn, SMP_CMD_PAIRING_RANDOM, |
2489 | sizeof(smp->prnd), smp->prnd); | 2647 | sizeof(smp->prnd), smp->prnd); |
@@ -2556,6 +2714,8 @@ static int smp_cmd_dhkey_check(struct l2cap_conn *conn, struct sk_buff *skb) | |||
2556 | 2714 | ||
2557 | if (smp->method == REQ_PASSKEY || smp->method == DSP_PASSKEY) | 2715 | if (smp->method == REQ_PASSKEY || smp->method == DSP_PASSKEY) |
2558 | put_unaligned_le32(hcon->passkey_notify, r); | 2716 | put_unaligned_le32(hcon->passkey_notify, r); |
2717 | else if (smp->method == REQ_OOB) | ||
2718 | memcpy(r, smp->lr, 16); | ||
2559 | 2719 | ||
2560 | err = smp_f6(smp->tfm_cmac, smp->mackey, smp->rrnd, smp->prnd, r, | 2720 | err = smp_f6(smp->tfm_cmac, smp->mackey, smp->rrnd, smp->prnd, r, |
2561 | io_cap, remote_addr, local_addr, e); | 2721 | io_cap, remote_addr, local_addr, e); |
@@ -2930,27 +3090,49 @@ static const struct l2cap_ops smp_root_chan_ops = { | |||
2930 | static struct l2cap_chan *smp_add_cid(struct hci_dev *hdev, u16 cid) | 3090 | static struct l2cap_chan *smp_add_cid(struct hci_dev *hdev, u16 cid) |
2931 | { | 3091 | { |
2932 | struct l2cap_chan *chan; | 3092 | struct l2cap_chan *chan; |
2933 | struct crypto_blkcipher *tfm_aes; | 3093 | struct smp_dev *smp; |
3094 | struct crypto_blkcipher *tfm_aes; | ||
3095 | struct crypto_hash *tfm_cmac; | ||
2934 | 3096 | ||
2935 | if (cid == L2CAP_CID_SMP_BREDR) { | 3097 | if (cid == L2CAP_CID_SMP_BREDR) { |
2936 | tfm_aes = NULL; | 3098 | smp = NULL; |
2937 | goto create_chan; | 3099 | goto create_chan; |
2938 | } | 3100 | } |
2939 | 3101 | ||
2940 | tfm_aes = crypto_alloc_blkcipher("ecb(aes)", 0, 0); | 3102 | smp = kzalloc(sizeof(*smp), GFP_KERNEL); |
3103 | if (!smp) | ||
3104 | return ERR_PTR(-ENOMEM); | ||
3105 | |||
3106 | tfm_aes = crypto_alloc_blkcipher("ecb(aes)", 0, CRYPTO_ALG_ASYNC); | ||
2941 | if (IS_ERR(tfm_aes)) { | 3107 | if (IS_ERR(tfm_aes)) { |
2942 | BT_ERR("Unable to create crypto context"); | 3108 | BT_ERR("Unable to create ECB crypto context"); |
3109 | kzfree(smp); | ||
2943 | return ERR_CAST(tfm_aes); | 3110 | return ERR_CAST(tfm_aes); |
2944 | } | 3111 | } |
2945 | 3112 | ||
3113 | tfm_cmac = crypto_alloc_hash("cmac(aes)", 0, CRYPTO_ALG_ASYNC); | ||
3114 | if (IS_ERR(tfm_cmac)) { | ||
3115 | BT_ERR("Unable to create CMAC crypto context"); | ||
3116 | crypto_free_blkcipher(tfm_aes); | ||
3117 | kzfree(smp); | ||
3118 | return ERR_CAST(tfm_cmac); | ||
3119 | } | ||
3120 | |||
3121 | smp->tfm_aes = tfm_aes; | ||
3122 | smp->tfm_cmac = tfm_cmac; | ||
3123 | |||
2946 | create_chan: | 3124 | create_chan: |
2947 | chan = l2cap_chan_create(); | 3125 | chan = l2cap_chan_create(); |
2948 | if (!chan) { | 3126 | if (!chan) { |
2949 | crypto_free_blkcipher(tfm_aes); | 3127 | if (smp) { |
3128 | crypto_free_blkcipher(smp->tfm_aes); | ||
3129 | crypto_free_hash(smp->tfm_cmac); | ||
3130 | kzfree(smp); | ||
3131 | } | ||
2950 | return ERR_PTR(-ENOMEM); | 3132 | return ERR_PTR(-ENOMEM); |
2951 | } | 3133 | } |
2952 | 3134 | ||
2953 | chan->data = tfm_aes; | 3135 | chan->data = smp; |
2954 | 3136 | ||
2955 | l2cap_add_scid(chan, cid); | 3137 | l2cap_add_scid(chan, cid); |
2956 | 3138 | ||
@@ -2983,14 +3165,18 @@ create_chan: | |||
2983 | 3165 | ||
2984 | static void smp_del_chan(struct l2cap_chan *chan) | 3166 | static void smp_del_chan(struct l2cap_chan *chan) |
2985 | { | 3167 | { |
2986 | struct crypto_blkcipher *tfm_aes; | 3168 | struct smp_dev *smp; |
2987 | 3169 | ||
2988 | BT_DBG("chan %p", chan); | 3170 | BT_DBG("chan %p", chan); |
2989 | 3171 | ||
2990 | tfm_aes = chan->data; | 3172 | smp = chan->data; |
2991 | if (tfm_aes) { | 3173 | if (smp) { |
2992 | chan->data = NULL; | 3174 | chan->data = NULL; |
2993 | crypto_free_blkcipher(tfm_aes); | 3175 | if (smp->tfm_aes) |
3176 | crypto_free_blkcipher(smp->tfm_aes); | ||
3177 | if (smp->tfm_cmac) | ||
3178 | crypto_free_hash(smp->tfm_cmac); | ||
3179 | kzfree(smp); | ||
2994 | } | 3180 | } |
2995 | 3181 | ||
2996 | l2cap_chan_put(chan); | 3182 | l2cap_chan_put(chan); |
diff --git a/net/bluetooth/smp.h b/net/bluetooth/smp.h index 60c5b73fcb4b..6cf872563ea7 100644 --- a/net/bluetooth/smp.h +++ b/net/bluetooth/smp.h | |||
@@ -188,6 +188,7 @@ int smp_user_confirm_reply(struct hci_conn *conn, u16 mgmt_op, __le32 passkey); | |||
188 | bool smp_irk_matches(struct hci_dev *hdev, const u8 irk[16], | 188 | bool smp_irk_matches(struct hci_dev *hdev, const u8 irk[16], |
189 | const bdaddr_t *bdaddr); | 189 | const bdaddr_t *bdaddr); |
190 | int smp_generate_rpa(struct hci_dev *hdev, const u8 irk[16], bdaddr_t *rpa); | 190 | int smp_generate_rpa(struct hci_dev *hdev, const u8 irk[16], bdaddr_t *rpa); |
191 | int smp_generate_oob(struct hci_dev *hdev, u8 hash[16], u8 rand[16]); | ||
191 | 192 | ||
192 | int smp_register(struct hci_dev *hdev); | 193 | int smp_register(struct hci_dev *hdev); |
193 | void smp_unregister(struct hci_dev *hdev); | 194 | void smp_unregister(struct hci_dev *hdev); |
diff --git a/net/mac802154/driver-ops.h b/net/mac802154/driver-ops.h index 98180a9fff4a..a0533357b9ea 100644 --- a/net/mac802154/driver-ops.h +++ b/net/mac802154/driver-ops.h | |||
@@ -1,4 +1,4 @@ | |||
1 | #ifndef __MAC802154_DRVIER_OPS | 1 | #ifndef __MAC802154_DRIVER_OPS |
2 | #define __MAC802154_DRIVER_OPS | 2 | #define __MAC802154_DRIVER_OPS |
3 | 3 | ||
4 | #include <linux/types.h> | 4 | #include <linux/types.h> |
@@ -220,4 +220,4 @@ drv_set_promiscuous_mode(struct ieee802154_local *local, bool on) | |||
220 | return local->ops->set_promiscuous_mode(&local->hw, on); | 220 | return local->ops->set_promiscuous_mode(&local->hw, on); |
221 | } | 221 | } |
222 | 222 | ||
223 | #endif /* __MAC802154_DRVIER_OPS */ | 223 | #endif /* __MAC802154_DRIVER_OPS */ |