Linux bluetooth development
 help / color / mirror / Atom feed
* [PATCH BlueZ 3/3] android: Load bluetooth.default.so as a module
From: Luiz Augusto von Dentz @ 2014-01-10 12:14 UTC (permalink / raw)
  To: linux-bluetooth
In-Reply-To: <1389356048-4333-1-git-send-email-luiz.dentz@gmail.com>

From: Luiz Augusto von Dentz <luiz.von.dentz@intel.com>

This makes haltest and android-tester to load bluetooth.default.so
instead of linking directly to it.
---
 android/Makefile.am         |  26 +++++-----
 android/hardware/hardware.c | 124 ++++++++++++++++++++++++++++++++++++++++++++
 2 files changed, 138 insertions(+), 12 deletions(-)
 create mode 100644 android/hardware/hardware.c

diff --git a/android/Makefile.am b/android/Makefile.am
index 4b843b2..f5e8c99 100644
--- a/android/Makefile.am
+++ b/android/Makefile.am
@@ -1,4 +1,6 @@
 if ANDROID
+android_plugindir = $(abs_top_srcdir)/android/.libs
+
 noinst_PROGRAMS += android/system-emulator
 
 android_system_emulator_SOURCES = android/system-emulator.c \
@@ -61,7 +63,8 @@ android_bluetooth_default_la_SOURCES = android/hal.h android/hal-bluetooth.c \
 					android/hardware/hardware.h \
 					android/cutils/properties.h \
 					android/hal-log.h \
-					android/hal-ipc.h android/hal-ipc.c
+					android/hal-ipc.h android/hal-ipc.c \
+					android/hal-utils.h android/hal-utils.c
 
 android_bluetooth_default_la_CPPFLAGS = -I$(srcdir)/android \
 					-DPLATFORM_SDK_VERSION=19
@@ -86,15 +89,14 @@ android_haltest_SOURCES = android/client/haltest.c \
 				android/client/if-hh.c \
 				android/client/if-pan.c \
 				android/client/if-sock.c \
-				android/client/hwmodule.c \
+				android/hardware/hardware.c \
 				android/hal-utils.h android/hal-utils.c
 
-android_haltest_LDADD = android/bluetooth.default.la
-
 android_haltest_CFLAGS = $(AM_CFLAGS) -I$(srcdir)/android \
-				-DPLATFORM_SDK_VERSION=19
+				-DPLATFORM_SDK_VERSION=19 \
+				-DPLUGINDIR=\""$(android_plugindir)"\"
 
-android_haltest_LDFLAGS = -pthread
+android_haltest_LDFLAGS = -pthread -ldl
 
 noinst_PROGRAMS += android/android-tester
 
@@ -106,15 +108,15 @@ android_android_tester_SOURCES = emulator/btdev.h emulator/btdev.c \
 				src/shared/mgmt.h src/shared/mgmt.c \
 				src/shared/hciemu.h src/shared/hciemu.c \
 				src/shared/tester.h src/shared/tester.c \
-				android/hal-utils.h android/hal-utils.c \
-				android/client/hwmodule.c android/android-tester.c
+				android/hardware/hardware.c \
+				android/android-tester.c
 
-android_android_tester_CFLAGS = $(AM_CFLAGS) -I$(srcdir)/android
+android_android_tester_CFLAGS = $(AM_CFLAGS) -I$(srcdir)/android \
+				-DPLUGINDIR=\""$(android_plugindir)"\"
 
-android_android_tester_LDADD = lib/libbluetooth-internal.la \
-				android/bluetooth.default.la @GLIB_LIBS@
+android_android_tester_LDADD = lib/libbluetooth-internal.la @GLIB_LIBS@
 
-android_android_tester_LDFLAGS = -pthread
+android_android_tester_LDFLAGS = -pthread -ldl
 
 plugin_LTLIBRARIES += android/audio.a2dp.default.la
 
diff --git a/android/hardware/hardware.c b/android/hardware/hardware.c
new file mode 100644
index 0000000..4bd5eba
--- /dev/null
+++ b/android/hardware/hardware.c
@@ -0,0 +1,124 @@
+/*
+ * Copyright (C) 2008 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#include <hardware/hardware.h>
+
+#include <dlfcn.h>
+#include <string.h>
+#include <pthread.h>
+#include <errno.h>
+#include <limits.h>
+#include <stdio.h>
+
+#define LOG_TAG "HAL"
+
+#define LOG_INFO " I"
+#define LOG_WARN " W"
+#define LOG_ERROR " E"
+#define LOG_DEBUG " D"
+#define ALOG(pri, tag, fmt, arg...) fprintf(stderr, tag pri": " fmt"\n", ##arg)
+
+#define info(fmt, arg...) ALOG(LOG_INFO, LOG_TAG, fmt, ##arg)
+#define warn(fmt, arg...) ALOG(LOG_WARN, LOG_TAG, fmt, ##arg)
+#define error(fmt, arg...) ALOG(LOG_ERROR, LOG_TAG, fmt, ##arg)
+
+/**
+ * Load the file defined by the variant and if successful
+ * return the dlopen handle and the hmi.
+ * @return 0 = success, !0 = failure.
+ */
+static int load(const char *id,
+        const char *path,
+        const struct hw_module_t **pHmi)
+{
+    int status;
+    void *handle;
+    struct hw_module_t *hmi;
+    const char *sym = HAL_MODULE_INFO_SYM_AS_STR;
+
+    /*
+     * load the symbols resolving undefined symbols before
+     * dlopen returns. Since RTLD_GLOBAL is not or'd in with
+     * RTLD_NOW the external symbols will not be global
+     */
+    handle = dlopen(path, RTLD_NOW);
+    if (handle == NULL) {
+        char const *err_str = dlerror();
+        error("load: module=%s\n%s", path, err_str?err_str:"unknown");
+        status = -EINVAL;
+        goto done;
+    }
+
+    /* Get the address of the struct hal_module_info. */
+    hmi = (struct hw_module_t *)dlsym(handle, sym);
+    if (hmi == NULL) {
+        error("load: couldn't find symbol %s", sym);
+        status = -EINVAL;
+        goto done;
+    }
+
+    /* Check that the id matches */
+    if (strcmp(id, hmi->id) != 0) {
+        error("load: id=%s != hmi->id=%s", id, hmi->id);
+        status = -EINVAL;
+        goto done;
+    }
+
+    hmi->dso = handle;
+
+    *pHmi = hmi;
+
+    info("loaded HAL id=%s path=%s hmi=%p handle=%p",
+                id, path, *pHmi, handle);
+
+    return 0;
+
+done:
+    hmi = NULL;
+    if (handle != NULL) {
+        dlclose(handle);
+        handle = NULL;
+    }
+
+    return status;
+}
+
+int hw_get_module_by_class(const char *class_id, const char *inst,
+                           const struct hw_module_t **module)
+{
+    char path[PATH_MAX];
+    char name[PATH_MAX];
+
+    if (inst)
+        snprintf(name, PATH_MAX, "%s.%s", class_id, inst);
+    else
+        snprintf(name, PATH_MAX, "%s", class_id);
+
+    /*
+     * Here we rely on the fact that calling dlopen multiple times on
+     * the same .so will simply increment a refcount (and not load
+     * a new copy of the library).
+     * We also assume that dlopen() is thread-safe.
+     */
+    snprintf(path, sizeof(path), "%s/%s.default.so", PLUGINDIR, name);
+
+    return load(class_id, path, module);
+}
+
+int hw_get_module(const char *id, const struct hw_module_t **module)
+{
+    return hw_get_module_by_class(id, NULL, module);
+}
-- 
1.8.4.2


^ permalink raw reply related

* [PATCH BlueZ 2/3] android: Convert libhal-internal to a plugin
From: Luiz Augusto von Dentz @ 2014-01-10 12:14 UTC (permalink / raw)
  To: linux-bluetooth
In-Reply-To: <1389356048-4333-1-git-send-email-luiz.dentz@gmail.com>

From: Luiz Augusto von Dentz <luiz.von.dentz@intel.com>

This convert the static library libhal-internal.la to
bluetooth.default.la when building with autotools.
---
 android/Makefile.am | 12 +++++++-----
 1 file changed, 7 insertions(+), 5 deletions(-)

diff --git a/android/Makefile.am b/android/Makefile.am
index 97173db..4b843b2 100644
--- a/android/Makefile.am
+++ b/android/Makefile.am
@@ -39,9 +39,9 @@ android_bluetoothd_SOURCES = android/main.c \
 
 android_bluetoothd_LDADD = lib/libbluetooth-internal.la @GLIB_LIBS@
 
-noinst_LTLIBRARIES += android/libhal-internal.la
+plugin_LTLIBRARIES += android/bluetooth.default.la
 
-android_libhal_internal_la_SOURCES = android/hal.h android/hal-bluetooth.c \
+android_bluetooth_default_la_SOURCES = android/hal.h android/hal-bluetooth.c \
 					android/hal-sock.c \
 					android/hal-hidhost.c \
 					android/hal-pan.c \
@@ -63,8 +63,10 @@ android_libhal_internal_la_SOURCES = android/hal.h android/hal-bluetooth.c \
 					android/hal-log.h \
 					android/hal-ipc.h android/hal-ipc.c
 
-android_libhal_internal_la_CPPFLAGS = -I$(srcdir)/android \
+android_bluetooth_default_la_CPPFLAGS = -I$(srcdir)/android \
 					-DPLATFORM_SDK_VERSION=19
+android_bluetooth_default_la_LDFLAGS = $(AM_LDFLAGS) -module -avoid-version \
+					-no-undefined
 
 noinst_PROGRAMS += android/haltest
 
@@ -87,7 +89,7 @@ android_haltest_SOURCES = android/client/haltest.c \
 				android/client/hwmodule.c \
 				android/hal-utils.h android/hal-utils.c
 
-android_haltest_LDADD = android/libhal-internal.la
+android_haltest_LDADD = android/bluetooth.default.la
 
 android_haltest_CFLAGS = $(AM_CFLAGS) -I$(srcdir)/android \
 				-DPLATFORM_SDK_VERSION=19
@@ -110,7 +112,7 @@ android_android_tester_SOURCES = emulator/btdev.h emulator/btdev.c \
 android_android_tester_CFLAGS = $(AM_CFLAGS) -I$(srcdir)/android
 
 android_android_tester_LDADD = lib/libbluetooth-internal.la \
-				android/libhal-internal.la @GLIB_LIBS@
+				android/bluetooth.default.la @GLIB_LIBS@
 
 android_android_tester_LDFLAGS = -pthread
 
-- 
1.8.4.2


^ permalink raw reply related

* [PATCH BlueZ 1/3] android: Convert libaudio-internal to a plugin
From: Luiz Augusto von Dentz @ 2014-01-10 12:14 UTC (permalink / raw)
  To: linux-bluetooth

From: Luiz Augusto von Dentz <luiz.von.dentz@intel.com>

This convert the static library libaudio-internal.la to
audio.a2dp.default.so when building with autotools.
---
 android/Makefile.am | 9 +++++----
 1 file changed, 5 insertions(+), 4 deletions(-)

diff --git a/android/Makefile.am b/android/Makefile.am
index 0a32a95..97173db 100644
--- a/android/Makefile.am
+++ b/android/Makefile.am
@@ -114,18 +114,19 @@ android_android_tester_LDADD = lib/libbluetooth-internal.la \
 
 android_android_tester_LDFLAGS = -pthread
 
-noinst_LTLIBRARIES += android/libaudio-internal.la
+plugin_LTLIBRARIES += android/audio.a2dp.default.la
 
-android_libaudio_internal_la_SOURCES = android/audio-msg.h \
+android_audio_a2dp_default_la_SOURCES = android/audio-msg.h \
 					android/hal-audio.c \
 					android/hardware/audio.h \
 					android/hardware/audio_effect.h \
 					android/hardware/hardware.h \
 					android/system/audio.h
 
-android_libaudio_internal_la_CFLAGS = -I$(srcdir)/android
+android_audio_a2dp_default_la_CFLAGS = -I$(srcdir)/android
 
-android_libaudio_internal_la_LDFLAGS = -pthread
+android_audio_a2dp_default_la_LDFLAGS = $(AM_LDFLAGS) -module -avoid-version \
+					-no-undefined -pthread
 
 endif
 
-- 
1.8.4.2


^ permalink raw reply related

* Re: [PATCH] android/pts: Add PTS test results for L2CAP
From: Szymon Janc @ 2014-01-10 12:02 UTC (permalink / raw)
  To: Sebastian Chlad; +Cc: linux-bluetooth
In-Reply-To: <1389354460-7297-1-git-send-email-sebastianx.chlad@intel.com>

Hi Sebastian,

On Friday 10 of January 2014 13:47:40 Sebastian Chlad wrote:
> ---
>  android/pts-l2cap.txt | 128 +++++++++++++++++++++++++-------------------------
>  1 file changed, 64 insertions(+), 64 deletions(-)
> 
> diff --git a/android/pts-l2cap.txt b/android/pts-l2cap.txt
> index d293046..51eedf5 100644
> --- a/android/pts-l2cap.txt
> +++ b/android/pts-l2cap.txt
> @@ -1,7 +1,7 @@
>  PTS test results for L2CAP
>  
>  PTS version: 5.0
> -Tested: 18.12.2013
> +Tested: 10.01.2014
>  
>  Results:
>  PASS   test passed
> @@ -12,21 +12,21 @@ N/A    test is disabled due to PICS setup
>  -------------------------------------------------------------------------------
>  Test Name              Result  Notes
>  -------------------------------------------------------------------------------
> -TC_COS_CED_BV_01_C     PASS
> +TC_COS_CED_BV_01_C     PASS    l2test -n -P 33 <bdaddr>
>  TC_COS_CED_BV_03_C     PASS
>  TC_COS_CED_BV_04_C     N/A
>  TC_COS_CED_BV_05_C     PASS
>  TC_COS_CED_BV_07_C     PASS
>  TC_COS_CED_BV_08_C     PASS
> -TC_COS_CED_BV_09_C     INC
> +TC_COS_CED_BV_09_C     PASS
>  TC_COS_CED_BV_10_C     N/A
>  TC_COS_CED_BV_11_C     PASS
>  TC_COS_CED_BI_01_C     PASS
>  TC_COS_CFD_BV_01_C     PASS
>  TC_COS_CFD_BV_02_C     PASS
>  TC_COS_CFD_BV_03_C     PASS
> -TC_COS_CFD_BV_08_C     INC
> -TC_COS_CFD_BV_09_C     INC
> +TC_COS_CFD_BV_08_C     PASS
> +TC_COS_CFD_BV_09_C     PASS
>  TC_COS_CFD_BV_10_C     N/A
>  TC_COS_CFD_BI_11_C     PASS
>  TC_COS_CFD_BV_12_C     PASS
> @@ -34,7 +34,7 @@ TC_COS_CFD_BV_13_C     N/A
>  TC_COS_IEX_BV_01_C     PASS
>  TC_COS_IEX_BV_02_C     PASS
>  TC_COS_ECH_BV_01_C     PASS
> -TC_COS_ECH_BV_02_C     INC
> +TC_COS_ECH_BV_02_C     PASS
>  TC_CLS_CLR_BV_01_C     N/A
>  TC_CLS_UCD_BV_01_C     N/A
>  TC_CLS_UCD_BV_02_C     N/A
> @@ -45,75 +45,75 @@ TC_EXF_BV_03_C         PASS
>  TC_EXF_BV_04_C         N/A
>  TC_EXF_BV_05_C         PASS
>  TC_EXF_BV_06_C         N/A
> -TC_CMC_BV_01_C         INC
> -TC_CMC_BV_02_C         INC
> -TC_CMC_BV_03_C         INC
> -TC_CMC_BV_04_C         INC
> -TC_CMC_BV_05_C         INC
> -TC_CMC_BV_06_C         INC
> -TC_CMC_BV_07_C         INC
> -TC_CMC_BV_08_C         INC
> -TC_CMC_BV_09_C         INC
> -TC_CMC_BV_10_C         INC
> -TC_CMC_BV_11_C         INC
> -TC_CMC_BV_12_C         INC
> -TC_CMC_BV_13_C         INC
> -TC_CMC_BV_14_C         INC
> -TC_CMC_BV_15_C         INC
> -TC_CMC_BI_01_C         INC
> -TC_CMC_BI_02_C         INC
> -TC_CMC_BI_03_C         INC
> -TC_CMC_BI_04_C         INC
> -TC_CMC_BI_05_C         INC
> -TC_CMC_BI_06_C         INC
> -TC_FOC_BV_01_C         INC
> -TC_FOC_BV_02_C         INC
> -TC_FOC_BV_03_C         INC
> -TC_FOC_BV_04_C         INC
> -TC_OFS_BV_01_C         INC
> -TC_OFS_BV_02_C         INC
> -TC_OFS_BV_03_C         INC
> -TC_OFS_BV_04_C         INC
> -TC_OFS_BV_05_C         INC
> -TC_OFS_BV_06_C         INC
> -TC_OFS_BV_07_C         INC
> -TC_OFS_BV_08_C         INC
> -TC_ERM_BV_01_C         INC
> -TC_ERM_BV_02_C         INC
> -TC_ERM_BV_03_C         INC
> -TC_ERM_BV_04_C         INC
> -TC_ERM_BV_05_C         INC
> -TC_ERM_BV_06_C         INC
> -TC_ERM_BV_07_C         INC
> -TC_ERM_BV_08_C         INC
> -TC_ERM_BV_09_C         INC
> +TC_CMC_BV_01_C         PASS    l2test -X ertm -P 33 <bdaddr>
> +TC_CMC_BV_02_C         PASS    l2test -X ertm -P 33 <bdaddr>
> +TC_CMC_BV_03_C         PASS    l2test -X ertm -P 33 <bdaddr>
> +TC_CMC_BV_04_C         PASS    l2test -X streaming -P 33 <bdaddr>
> +TC_CMC_BV_05_C         PASS    l2test -X streaming -P 33 <bdaddr>
> +TC_CMC_BV_06_C         PASS    l2test -X streaming -P 33 <bdaddr>
> +TC_CMC_BV_07_C         PASS    l2test -X basic -P 33 <bdaddr>
> +TC_CMC_BV_08_C         PASS    l2test -X basic -P 33 <bdaddr>
> +TC_CMC_BV_09_C         PASS    l2test -X streaming -P 33 <bdaddr>
> +TC_CMC_BV_10_C         PASS    l2test -n <bdaddr>
> +TC_CMC_BV_11_C         PASS    l2test -n <bdaddr>
> +TC_CMC_BV_12_C         PASS    l2test -n -X ertm -P 33 <bdaddr>
> +TC_CMC_BV_13_C         PASS    l2test -s -X streaming -P 33 <bdaddr>
> +TC_CMC_BV_14_C         PASS    l2test -X streaming -P 33 <bdaddr>
> +TC_CMC_BV_15_C         PASS    l2test -X streaming -P 33 <bdaddr>
> +TC_CMC_BI_01_C         PASS
> +TC_CMC_BI_02_C         PASS
> +TC_CMC_BI_03_C         PASS
> +TC_CMC_BI_04_C         PASS
> +TC_CMC_BI_05_C         PASS
> +TC_CMC_BI_06_C         PASS
> +TC_FOC_BV_01_C         PASS    l2test -X ertm -P 33 -F 0 &
> +TC_FOC_BV_02_C         PASS    l2test -X ertm -P 33 -F 0 &
> +TC_FOC_BV_03_C         PASS    l2test -X ertm -P 33 -F 0 &
> +TC_FOC_BV_04_C         PASS    l2test -n -X ertm -P <bdaddr> &
> +TC_OFS_BV_01_C         PASS
> +TC_OFS_BV_02_C         PASS    l2test -X ertm -P 33 -F 0 &
> +TC_OFS_BV_03_C         PASS
> +TC_OFS_BV_04_C         PASS
> +TC_OFS_BV_05_C         PASS    l2test -X ertm -P 33 -F 0 &
> +TC_OFS_BV_06_C         PASS    l2test -X ertm -P 33 -F 0 &
> +TC_OFS_BV_07_C         PASS
> +TC_OFS_BV_08_C         PASS
> +TC_ERM_BV_01_C         PASS    l2test -X ertm -P 33 -B -Y 3 &
> +TC_ERM_BV_02_C         PASS    l2test -X ertm -P 33 &
> +TC_ERM_BV_03_C         PASS    l2test -X ertm -P 33 &
> +TC_ERM_BV_04_C         PASS    l2test -X ertm -P 33 -B &
> +TC_ERM_BV_05_C         PASS
> +TC_ERM_BV_06_C         PASS
> +TC_ERM_BV_07_C         PASS    l2test -X ertm -P 33 &
> +TC_ERM_BV_08_C         PASS
> +TC_ERM_BV_09_C         PASS    l2test -X ertm -P 33 &
>  TC_ERM_BV_10_C         INC
>  TC_ERM_BV_11_C         INC
>  TC_ERM_BV_12_C         INC
> -TC_ERM_BV_13_C         INC
> -TC_ERM_BV_14_C         INC
> -TC_ERM_BV_15_C         INC
> -TC_ERM_BV_16_C         INC
> -TC_ERM_BV_17_C         INC
> +TC_ERM_BV_13_C         PASS
> +TC_ERM_BV_14_C         PASS
> +TC_ERM_BV_15_C         PASS
> +TC_ERM_BV_16_C         PASS
> +TC_ERM_BV_17_C         PASS
>  TC_ERM_BV_18_C         INC
>  TC_ERM_BV_19_C         INC
> -TC_ERM_BV_20_C         INC
> -TC_ERM_BV_21_C         INC
> -TC_ERM_BV_22_C         INC
> -TC_ERM_BV_23_C         INC
> -TC_ERM_BI_01_C         INC
> -TC_ERM_BI_02_C         INC
> -TC_ERM_BI_03_C         INC
> -TC_ERM_BI_04_C         INC
> -TC_ERM_BI_05_C         INC
> +TC_ERM_BV_20_C         PASS
> +TC_ERM_BV_21_C         PASS
> +TC_ERM_BV_22_C         PASS
> +TC_ERM_BV_23_C         PASS
> +TC_ERM_BI_01_C         PASS
> +TC_ERM_BI_02_C         PASS
> +TC_ERM_BI_03_C         PASS
> +TC_ERM_BI_04_C         PASS
> +TC_ERM_BI_05_C         PASS
>  TC_STM_BV_01_C         INC
>  TC_STM_BV_02_C         INC
>  TC_STM_BV_03_C         INC
>  TC_STM_BV_11_C         N/A
>  TC_STM_BV_12_C         N/A
>  TC_STM_BV_13_C         N/A
> -TC_FIX_BV_01_C         PASS
> -TC_FIX_BV_02_C         PASS
> +TC_FIX_BV_01_C         PASS    l2test -n -P 33 <bdaddr>
> +TC_FIX_BV_02_C         N/A
>  TC_EWC_BV_01_C         N/A
>  TC_EWC_BV_02_C         N/A
>  TC_EWC_BV_03_C         N/A
> 

Applied, thanks.

-- 
Best regards, 
Szymon Janc

^ permalink raw reply

* [PATCH_v5 4/4] android/pan: Remove connected PAN devices on profile unregister call
From: Ravi kumar Veeramally @ 2014-01-10 11:52 UTC (permalink / raw)
  To: linux-bluetooth; +Cc: Ravi kumar Veeramally
In-Reply-To: <1389354776-18098-1-git-send-email-ravikumar.veeramally@linux.intel.com>

---
 android/pan.c | 10 ++++++++++
 1 file changed, 10 insertions(+)

diff --git a/android/pan.c b/android/pan.c
index a733d22..8ea07a4 100644
--- a/android/pan.c
+++ b/android/pan.c
@@ -750,10 +750,20 @@ bool bt_pan_register(const bdaddr_t *addr)
 	return true;
 }
 
+static void pan_device_disconnected(gpointer data, gpointer user_data)
+{
+	struct pan_device *dev = data;
+
+	bt_pan_notify_conn_state(dev, HAL_PAN_STATE_DISCONNECTED);
+}
+
 void bt_pan_unregister(void)
 {
 	DBG("");
 
+	g_slist_foreach(devices, pan_device_disconnected, NULL);
+	devices = NULL;
+
 	bnep_cleanup();
 
 	ipc_unregister(HAL_SERVICE_ID_PAN);
-- 
1.8.3.2


^ permalink raw reply related

* [PATCH_v5 3/4] android/pan: Implement PAN enable HAL api at daemon side
From: Ravi kumar Veeramally @ 2014-01-10 11:52 UTC (permalink / raw)
  To: linux-bluetooth; +Cc: Ravi kumar Veeramally
In-Reply-To: <1389354776-18098-1-git-send-email-ravikumar.veeramally@linux.intel.com>

---
 android/pan.c | 30 ++++++++++++++++++++++++++----
 1 file changed, 26 insertions(+), 4 deletions(-)

diff --git a/android/pan.c b/android/pan.c
index d683945..a733d22 100644
--- a/android/pan.c
+++ b/android/pan.c
@@ -574,18 +574,40 @@ static void bt_pan_enable(const void *buf, uint16_t len)
 {
 	const struct hal_cmd_pan_enable *cmd = buf;
 	uint8_t status;
+	int err;
+
+	DBG("");
+
+	if (local_role == cmd->local_role) {
+		status = HAL_STATUS_SUCCESS;
+		goto reply;
+	}
+
+	/* destroy existing server */
+	destroy_nap_device();
 
 	switch (cmd->local_role) {
-	case HAL_PAN_ROLE_PANU:
 	case HAL_PAN_ROLE_NAP:
-		DBG("Not Implemented");
-		status  = HAL_STATUS_FAILED;
 		break;
+	case HAL_PAN_ROLE_NONE:
+		status = HAL_STATUS_SUCCESS;
+		goto reply;
 	default:
 		status = HAL_STATUS_UNSUPPORTED;
-		break;
+		goto reply;
 	}
 
+	local_role = cmd->local_role;
+	err = register_nap_server();
+	if (err < 0) {
+		status = HAL_STATUS_FAILED;
+		destroy_nap_device();
+		goto reply;
+	}
+
+	status = HAL_STATUS_SUCCESS;
+
+reply:
 	ipc_send_rsp(HAL_SERVICE_ID_PAN, HAL_OP_PAN_ENABLE, status);
 }
 
-- 
1.8.3.2


^ permalink raw reply related

* [PATCH_v5 2/4] android/pan: Listen for incoming connections and accept in NAP role
From: Ravi kumar Veeramally @ 2014-01-10 11:52 UTC (permalink / raw)
  To: linux-bluetooth; +Cc: Ravi kumar Veeramally
In-Reply-To: <1389354776-18098-1-git-send-email-ravikumar.veeramally@linux.intel.com>

Listen for incoming connections and accept it. Create bnep interface
add it to bridge and notify control and connection state information
through HAL. Remove the device on disconnect request. If android
settings UI does not have bluetooth tethering enabled it immediately
sends disconnect signal.
---
 android/pan.c | 185 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++-
 1 file changed, 182 insertions(+), 3 deletions(-)

diff --git a/android/pan.c b/android/pan.c
index ea0e34e..d683945 100644
--- a/android/pan.c
+++ b/android/pan.c
@@ -63,12 +63,15 @@ struct pan_device {
 	uint8_t		role;
 	GIOChannel	*io;
 	struct bnep	*session;
+	guint		watch;
 };
 
 static struct {
 	uint32_t	record_id;
+	GIOChannel	*io;
 } nap_dev = {
 	.record_id = 0,
+	.io = NULL,
 };
 
 static int device_cmp(gconstpointer s, gconstpointer user_data)
@@ -81,13 +84,19 @@ static int device_cmp(gconstpointer s, gconstpointer user_data)
 
 static void pan_device_free(struct pan_device *dev)
 {
+	if (dev->watch > 0) {
+		bnep_server_delete(BNEP_BRIDGE, dev->iface, &dev->dst);
+		g_source_remove(dev->watch);
+	}
+
 	if (dev->io) {
 		g_io_channel_shutdown(dev->io, FALSE, NULL);
 		g_io_channel_unref(dev->io);
-		dev->io = NULL;
 	}
 
-	bnep_free(dev->session);
+	if (dev->session)
+		bnep_free(dev->session);
+
 	devices = g_slist_remove(devices, dev);
 	g_free(dev);
 
@@ -298,7 +307,7 @@ static void bt_pan_disconnect(const void *buf, uint16_t len)
 
 	dev = l->data;
 
-	if (dev->conn_state == HAL_PAN_STATE_CONNECTED)
+	if (dev->conn_state == HAL_PAN_STATE_CONNECTED && dev->session)
 		bnep_disconnect(dev->session);
 
 	bt_pan_notify_conn_state(dev, HAL_PAN_STATE_DISCONNECTED);
@@ -308,6 +317,154 @@ failed:
 	ipc_send_rsp(HAL_SERVICE_ID_PAN, HAL_OP_PAN_DISCONNECT, status);
 }
 
+static gboolean nap_watchdog_cb(GIOChannel *chan, GIOCondition cond,
+							gpointer user_data)
+{
+	struct pan_device *dev = user_data;
+
+	DBG("disconnected");
+
+	bt_pan_notify_conn_state(dev, HAL_PAN_STATE_DISCONNECTED);
+
+	return FALSE;
+}
+static gboolean nap_setup_cb(GIOChannel *chan, GIOCondition cond,
+							gpointer user_data)
+{
+	struct pan_device *dev = user_data;
+	uint8_t packet[BNEP_MTU];
+	struct bnep_setup_conn_req *req = (void *) packet;
+	uint16_t src_role, dst_role, rsp = BNEP_CONN_NOT_ALLOWED;
+	int sk, n;
+
+	if (cond & (G_IO_ERR | G_IO_HUP | G_IO_NVAL)) {
+		error("Hangup or error or inval on BNEP socket");
+		return FALSE;
+	}
+
+	sk = g_io_channel_unix_get_fd(chan);
+
+	/* Reading BNEP_SETUP_CONNECTION_REQUEST_MSG */
+	n = read(sk, packet, sizeof(packet));
+	if (n  < 0) {
+		error("read(): %s(%d)", strerror(errno), errno);
+		goto failed;
+	}
+
+	/* Highest known control command id BNEP_FILTER_MULT_ADDR_RSP 0x06 */
+	if (req->type == BNEP_CONTROL &&
+			req->ctrl > BNEP_FILTER_MULT_ADDR_RSP) {
+		error("cmd not understood");
+		bnep_send_ctrl_rsp(sk, BNEP_CONTROL, BNEP_CMD_NOT_UNDERSTOOD,
+								req->ctrl);
+		goto failed;
+	}
+
+	if (req->type != BNEP_CONTROL || req->ctrl != BNEP_SETUP_CONN_REQ) {
+		error("cmd is not BNEP_SETUP_CONN_REQ %02X %02X", req->type,
+								req->ctrl);
+		goto failed;
+	}
+
+	rsp = bnep_setup_decode(req, &dst_role, &src_role);
+	if (rsp) {
+		error("bnep_setup_decode failed");
+		goto failed;
+	}
+
+	rsp = bnep_setup_chk(dst_role, src_role);
+	if (rsp) {
+		error("benp_setup_chk failed");
+		goto failed;
+	}
+
+	if (bnep_server_add(sk, dst_role, BNEP_BRIDGE, dev->iface,
+							&dev->dst) < 0) {
+		error("server_connadd failed");
+		rsp = BNEP_CONN_NOT_ALLOWED;
+		goto failed;
+	}
+
+	rsp = BNEP_SUCCESS;
+	bnep_send_ctrl_rsp(sk, BNEP_CONTROL, BNEP_SETUP_CONN_RSP, rsp);
+
+	dev->watch = g_io_add_watch(chan, G_IO_HUP | G_IO_ERR | G_IO_NVAL,
+							nap_watchdog_cb, dev);
+	g_io_channel_unref(dev->io);
+	dev->io = NULL;
+
+	bt_pan_notify_ctrl_state(dev, HAL_PAN_CTRL_ENABLED);
+	bt_pan_notify_conn_state(dev, HAL_PAN_STATE_CONNECTED);
+
+	return FALSE;
+
+failed:
+	bnep_send_ctrl_rsp(sk, BNEP_CONTROL, BNEP_SETUP_CONN_RSP, rsp);
+	pan_device_free(dev);
+
+	return FALSE;
+}
+
+static void nap_connect_cb(GIOChannel *chan, GError *err, gpointer user_data)
+{
+	struct pan_device *dev = user_data;
+
+	DBG("");
+
+	if (err) {
+		error("%s", err->message);
+		bt_pan_notify_conn_state(dev, HAL_PAN_STATE_DISCONNECTED);
+		return;
+	}
+
+	g_io_channel_set_close_on_unref(chan, TRUE);
+	dev->watch = g_io_add_watch(chan,
+				G_IO_IN | G_IO_HUP | G_IO_ERR | G_IO_NVAL,
+				nap_setup_cb, dev);
+}
+
+static void nap_confirm_cb(GIOChannel *chan, gpointer data)
+{
+	struct pan_device *dev = NULL;
+	bdaddr_t dst;
+	char address[18];
+	GError *err = NULL;
+
+	DBG("");
+
+	bt_io_get(chan, &err, BT_IO_OPT_DEST_BDADDR, &dst,
+			BT_IO_OPT_DEST, address, BT_IO_OPT_INVALID);
+	if (err) {
+		error("%s", err->message);
+		g_error_free(err);
+		goto failed;
+	}
+
+	DBG("incoming connect request from %s", address);
+	dev = g_new0(struct pan_device, 1);
+	bacpy(&dev->dst, &dst);
+	local_role = HAL_PAN_ROLE_NAP;
+	dev->role = HAL_PAN_ROLE_PANU;
+
+	dev->io = g_io_channel_ref(chan);
+	g_io_channel_set_close_on_unref(dev->io, TRUE);
+
+	if (!bt_io_accept(dev->io, nap_connect_cb, dev, NULL, &err)) {
+		error("bt_io_accept: %s", err->message);
+		g_error_free(err);
+		goto failed;
+	}
+
+	devices = g_slist_append(devices, dev);
+	bt_pan_notify_conn_state(dev, HAL_PAN_STATE_CONNECTING);
+
+	return;
+
+failed:
+	g_free(dev);
+	bt_pan_notify_conn_state(dev, HAL_PAN_STATE_DISCONNECTED);
+}
+
 static int set_forward_delay(void)
 {
 	int fd, ret;
@@ -376,10 +533,17 @@ static void destroy_nap_device(void)
 	DBG("");
 
 	nap_remove_bridge();
+
+	if (nap_dev.io) {
+		g_io_channel_shutdown(nap_dev.io, FALSE, NULL);
+		g_io_channel_unref(nap_dev.io);
+		nap_dev.io = NULL;
+	}
 }
 
 static int register_nap_server(void)
 {
+	GError *gerr;
 	int err;
 
 	DBG("");
@@ -388,6 +552,21 @@ static int register_nap_server(void)
 	if (err < 0)
 		return err;
 
+	nap_dev.io = bt_io_listen(NULL, nap_confirm_cb, NULL, NULL, &gerr,
+					BT_IO_OPT_SOURCE_BDADDR, &adapter_addr,
+					BT_IO_OPT_PSM, BNEP_PSM,
+					BT_IO_OPT_SEC_LEVEL, BT_IO_SEC_MEDIUM,
+					BT_IO_OPT_OMTU, BNEP_MTU,
+					BT_IO_OPT_IMTU, BNEP_MTU,
+					BT_IO_OPT_INVALID);
+
+	if (!nap_dev.io) {
+		destroy_nap_device();
+		error("%s", gerr->message);
+		g_error_free(gerr);
+		return -EINVAL;
+	}
+
 	return 0;
 }
 
-- 
1.8.3.2


^ permalink raw reply related

* [PATCH_v5 1/4] android/pan: Register Network Access Point
From: Ravi kumar Veeramally @ 2014-01-10 11:52 UTC (permalink / raw)
  To: linux-bluetooth; +Cc: Ravi kumar Veeramally
In-Reply-To: <1389354776-18098-1-git-send-email-ravikumar.veeramally@linux.intel.com>

Register NAP server and adds bnep bridge. Removes bridge
on destroy call. Bridge mechanism is needed when device acting
as a server and listen for incoming connections.
---
 android/pan.c | 112 +++++++++++++++++++++++++++++++++++++++++++++++++++++++---
 1 file changed, 107 insertions(+), 5 deletions(-)

diff --git a/android/pan.c b/android/pan.c
index 38e353d..ea0e34e 100644
--- a/android/pan.c
+++ b/android/pan.c
@@ -28,6 +28,11 @@
 #include <unistd.h>
 #include <fcntl.h>
 #include <glib.h>
+#include <sys/ioctl.h>
+#include <sys/socket.h>
+#include <sys/wait.h>
+#include <net/if.h>
+#include <linux/sockios.h>
 
 #include "btio/btio.h"
 #include "lib/bluetooth.h"
@@ -45,11 +50,11 @@
 #include "bluetooth.h"
 
 #define SVC_HINT_NETWORKING 0x02
+#define BNEP_BRIDGE	"bnep"
 
 static bdaddr_t adapter_addr;
 GSList *devices = NULL;
 uint8_t local_role = HAL_PAN_ROLE_NONE;
-static uint32_t record_id = 0;
 
 struct pan_device {
 	char		iface[16];
@@ -60,6 +65,12 @@ struct pan_device {
 	struct bnep	*session;
 };
 
+static struct {
+	uint32_t	record_id;
+} nap_dev = {
+	.record_id = 0,
+};
+
 static int device_cmp(gconstpointer s, gconstpointer user_data)
 {
 	const struct pan_device *dev = s;
@@ -297,6 +308,89 @@ failed:
 	ipc_send_rsp(HAL_SERVICE_ID_PAN, HAL_OP_PAN_DISCONNECT, status);
 }
 
+static int set_forward_delay(void)
+{
+	int fd, ret;
+	char path[41];
+
+	sprintf(path, "/sys/class/net/%s/bridge/forward_delay", BNEP_BRIDGE);
+
+	fd = open(path, O_RDWR);
+	if (fd < 0)
+		return -errno;
+
+	ret = write(fd, "0", sizeof("0"));
+	close(fd);
+
+	return ret;
+}
+
+static int nap_create_bridge(void)
+{
+	int sk, err;
+
+	DBG("%s", BNEP_BRIDGE);
+
+	sk = socket(AF_INET, SOCK_STREAM | SOCK_CLOEXEC, 0);
+	if (sk < 0)
+		return -EOPNOTSUPP;
+
+	if (ioctl(sk, SIOCBRADDBR, BNEP_BRIDGE) < 0) {
+		err = -errno;
+		if (err != -EEXIST) {
+			close(sk);
+			return -EOPNOTSUPP;
+		}
+	}
+
+	err = set_forward_delay();
+	if (err < 0)
+		ioctl(sk, SIOCBRDELBR, BNEP_BRIDGE);
+
+	close(sk);
+
+	return err;
+}
+
+static int nap_remove_bridge(void)
+{
+	int sk, err;
+
+	DBG("%s", BNEP_BRIDGE);
+
+	sk = socket(AF_INET, SOCK_STREAM | SOCK_CLOEXEC, 0);
+	if (sk < 0)
+		return -EOPNOTSUPP;
+
+	err = ioctl(sk, SIOCBRDELBR, BNEP_BRIDGE);
+	close(sk);
+
+	if (err < 0)
+		return -EOPNOTSUPP;
+
+	return 0;
+}
+
+static void destroy_nap_device(void)
+{
+	DBG("");
+
+	nap_remove_bridge();
+}
+
+static int register_nap_server(void)
+{
+	int err;
+
+	DBG("");
+
+	err = nap_create_bridge();
+	if (err < 0)
+		return err;
+
+	return 0;
+}
+
 static void bt_pan_enable(const void *buf, uint16_t len)
 {
 	const struct hal_cmd_pan_enable *cmd = buf;
@@ -437,11 +531,18 @@ bool bt_pan_register(const bdaddr_t *addr)
 	err = bnep_init();
 	if (err) {
 		error("bnep init failed");
-		sdp_record_free(rec);
+		bt_adapter_remove_record(rec->handle);
+		return false;
+	}
+
+	err = register_nap_server();
+	if (err < 0) {
+		bt_adapter_remove_record(rec->handle);
+		bnep_cleanup();
 		return false;
 	}
 
-	record_id = rec->handle;
+	nap_dev.record_id = rec->handle;
 	ipc_register(HAL_SERVICE_ID_PAN, cmd_handlers,
 						G_N_ELEMENTS(cmd_handlers));
 
@@ -455,6 +556,7 @@ void bt_pan_unregister(void)
 	bnep_cleanup();
 
 	ipc_unregister(HAL_SERVICE_ID_PAN);
-	bt_adapter_remove_record(record_id);
-	record_id = 0;
+	bt_adapter_remove_record(nap_dev.record_id);
+	nap_dev.record_id = 0;
+	destroy_nap_device();
 }
-- 
1.8.3.2


^ permalink raw reply related

* [PATCH_v5 0/4] Add support for NAP role
From: Ravi kumar Veeramally @ 2014-01-10 11:52 UTC (permalink / raw)
  To: linux-bluetooth; +Cc: Ravi kumar Veeramally

v5: Fixed Szymon's comments and added his fix (crash when bridge create
    fails).

v4: Fixed Szymon's and Luiz's comments.

v3: Fixed Johan's comments (removed fopen, fprintf and used open and write).

v2: Fixed Johan's comments.

v1: This patch set add support for NAP role. It register NAP server and create
  bnep bridge and listen for incoming connections from client devices.
  On incoming connection request it accepts connection, creates bnep interface
  and notifies control state and connection state infromation. Removes device
  on disconnect request. Android related changes are required to enable this
  role. Patches sent to respective ML.

Ravi kumar Veeramally (4):
  android/pan: Register Network Access Point
  android/pan: Listen for incoming connections and accept in NAP role
  android/pan: Implement PAN enable HAL api at daemon side
  android/pan: Remove connected PAN devices on profile unregister call

 android/pan.c | 337 +++++++++++++++++++++++++++++++++++++++++++++++++++++++---
 1 file changed, 325 insertions(+), 12 deletions(-)

-- 
1.8.3.2


^ permalink raw reply

* [PATCH] android/pts: Add PTS test results for L2CAP
From: Sebastian Chlad @ 2014-01-10 11:47 UTC (permalink / raw)
  To: linux-bluetooth; +Cc: Sebastian Chlad

---
 android/pts-l2cap.txt | 128 +++++++++++++++++++++++++-------------------------
 1 file changed, 64 insertions(+), 64 deletions(-)

diff --git a/android/pts-l2cap.txt b/android/pts-l2cap.txt
index d293046..51eedf5 100644
--- a/android/pts-l2cap.txt
+++ b/android/pts-l2cap.txt
@@ -1,7 +1,7 @@
 PTS test results for L2CAP
 
 PTS version: 5.0
-Tested: 18.12.2013
+Tested: 10.01.2014
 
 Results:
 PASS   test passed
@@ -12,21 +12,21 @@ N/A    test is disabled due to PICS setup
 -------------------------------------------------------------------------------
 Test Name              Result  Notes
 -------------------------------------------------------------------------------
-TC_COS_CED_BV_01_C     PASS
+TC_COS_CED_BV_01_C     PASS    l2test -n -P 33 <bdaddr>
 TC_COS_CED_BV_03_C     PASS
 TC_COS_CED_BV_04_C     N/A
 TC_COS_CED_BV_05_C     PASS
 TC_COS_CED_BV_07_C     PASS
 TC_COS_CED_BV_08_C     PASS
-TC_COS_CED_BV_09_C     INC
+TC_COS_CED_BV_09_C     PASS
 TC_COS_CED_BV_10_C     N/A
 TC_COS_CED_BV_11_C     PASS
 TC_COS_CED_BI_01_C     PASS
 TC_COS_CFD_BV_01_C     PASS
 TC_COS_CFD_BV_02_C     PASS
 TC_COS_CFD_BV_03_C     PASS
-TC_COS_CFD_BV_08_C     INC
-TC_COS_CFD_BV_09_C     INC
+TC_COS_CFD_BV_08_C     PASS
+TC_COS_CFD_BV_09_C     PASS
 TC_COS_CFD_BV_10_C     N/A
 TC_COS_CFD_BI_11_C     PASS
 TC_COS_CFD_BV_12_C     PASS
@@ -34,7 +34,7 @@ TC_COS_CFD_BV_13_C     N/A
 TC_COS_IEX_BV_01_C     PASS
 TC_COS_IEX_BV_02_C     PASS
 TC_COS_ECH_BV_01_C     PASS
-TC_COS_ECH_BV_02_C     INC
+TC_COS_ECH_BV_02_C     PASS
 TC_CLS_CLR_BV_01_C     N/A
 TC_CLS_UCD_BV_01_C     N/A
 TC_CLS_UCD_BV_02_C     N/A
@@ -45,75 +45,75 @@ TC_EXF_BV_03_C         PASS
 TC_EXF_BV_04_C         N/A
 TC_EXF_BV_05_C         PASS
 TC_EXF_BV_06_C         N/A
-TC_CMC_BV_01_C         INC
-TC_CMC_BV_02_C         INC
-TC_CMC_BV_03_C         INC
-TC_CMC_BV_04_C         INC
-TC_CMC_BV_05_C         INC
-TC_CMC_BV_06_C         INC
-TC_CMC_BV_07_C         INC
-TC_CMC_BV_08_C         INC
-TC_CMC_BV_09_C         INC
-TC_CMC_BV_10_C         INC
-TC_CMC_BV_11_C         INC
-TC_CMC_BV_12_C         INC
-TC_CMC_BV_13_C         INC
-TC_CMC_BV_14_C         INC
-TC_CMC_BV_15_C         INC
-TC_CMC_BI_01_C         INC
-TC_CMC_BI_02_C         INC
-TC_CMC_BI_03_C         INC
-TC_CMC_BI_04_C         INC
-TC_CMC_BI_05_C         INC
-TC_CMC_BI_06_C         INC
-TC_FOC_BV_01_C         INC
-TC_FOC_BV_02_C         INC
-TC_FOC_BV_03_C         INC
-TC_FOC_BV_04_C         INC
-TC_OFS_BV_01_C         INC
-TC_OFS_BV_02_C         INC
-TC_OFS_BV_03_C         INC
-TC_OFS_BV_04_C         INC
-TC_OFS_BV_05_C         INC
-TC_OFS_BV_06_C         INC
-TC_OFS_BV_07_C         INC
-TC_OFS_BV_08_C         INC
-TC_ERM_BV_01_C         INC
-TC_ERM_BV_02_C         INC
-TC_ERM_BV_03_C         INC
-TC_ERM_BV_04_C         INC
-TC_ERM_BV_05_C         INC
-TC_ERM_BV_06_C         INC
-TC_ERM_BV_07_C         INC
-TC_ERM_BV_08_C         INC
-TC_ERM_BV_09_C         INC
+TC_CMC_BV_01_C         PASS    l2test -X ertm -P 33 <bdaddr>
+TC_CMC_BV_02_C         PASS    l2test -X ertm -P 33 <bdaddr>
+TC_CMC_BV_03_C         PASS    l2test -X ertm -P 33 <bdaddr>
+TC_CMC_BV_04_C         PASS    l2test -X streaming -P 33 <bdaddr>
+TC_CMC_BV_05_C         PASS    l2test -X streaming -P 33 <bdaddr>
+TC_CMC_BV_06_C         PASS    l2test -X streaming -P 33 <bdaddr>
+TC_CMC_BV_07_C         PASS    l2test -X basic -P 33 <bdaddr>
+TC_CMC_BV_08_C         PASS    l2test -X basic -P 33 <bdaddr>
+TC_CMC_BV_09_C         PASS    l2test -X streaming -P 33 <bdaddr>
+TC_CMC_BV_10_C         PASS    l2test -n <bdaddr>
+TC_CMC_BV_11_C         PASS    l2test -n <bdaddr>
+TC_CMC_BV_12_C         PASS    l2test -n -X ertm -P 33 <bdaddr>
+TC_CMC_BV_13_C         PASS    l2test -s -X streaming -P 33 <bdaddr>
+TC_CMC_BV_14_C         PASS    l2test -X streaming -P 33 <bdaddr>
+TC_CMC_BV_15_C         PASS    l2test -X streaming -P 33 <bdaddr>
+TC_CMC_BI_01_C         PASS
+TC_CMC_BI_02_C         PASS
+TC_CMC_BI_03_C         PASS
+TC_CMC_BI_04_C         PASS
+TC_CMC_BI_05_C         PASS
+TC_CMC_BI_06_C         PASS
+TC_FOC_BV_01_C         PASS    l2test -X ertm -P 33 -F 0 &
+TC_FOC_BV_02_C         PASS    l2test -X ertm -P 33 -F 0 &
+TC_FOC_BV_03_C         PASS    l2test -X ertm -P 33 -F 0 &
+TC_FOC_BV_04_C         PASS    l2test -n -X ertm -P <bdaddr> &
+TC_OFS_BV_01_C         PASS
+TC_OFS_BV_02_C         PASS    l2test -X ertm -P 33 -F 0 &
+TC_OFS_BV_03_C         PASS
+TC_OFS_BV_04_C         PASS
+TC_OFS_BV_05_C         PASS    l2test -X ertm -P 33 -F 0 &
+TC_OFS_BV_06_C         PASS    l2test -X ertm -P 33 -F 0 &
+TC_OFS_BV_07_C         PASS
+TC_OFS_BV_08_C         PASS
+TC_ERM_BV_01_C         PASS    l2test -X ertm -P 33 -B -Y 3 &
+TC_ERM_BV_02_C         PASS    l2test -X ertm -P 33 &
+TC_ERM_BV_03_C         PASS    l2test -X ertm -P 33 &
+TC_ERM_BV_04_C         PASS    l2test -X ertm -P 33 -B &
+TC_ERM_BV_05_C         PASS
+TC_ERM_BV_06_C         PASS
+TC_ERM_BV_07_C         PASS    l2test -X ertm -P 33 &
+TC_ERM_BV_08_C         PASS
+TC_ERM_BV_09_C         PASS    l2test -X ertm -P 33 &
 TC_ERM_BV_10_C         INC
 TC_ERM_BV_11_C         INC
 TC_ERM_BV_12_C         INC
-TC_ERM_BV_13_C         INC
-TC_ERM_BV_14_C         INC
-TC_ERM_BV_15_C         INC
-TC_ERM_BV_16_C         INC
-TC_ERM_BV_17_C         INC
+TC_ERM_BV_13_C         PASS
+TC_ERM_BV_14_C         PASS
+TC_ERM_BV_15_C         PASS
+TC_ERM_BV_16_C         PASS
+TC_ERM_BV_17_C         PASS
 TC_ERM_BV_18_C         INC
 TC_ERM_BV_19_C         INC
-TC_ERM_BV_20_C         INC
-TC_ERM_BV_21_C         INC
-TC_ERM_BV_22_C         INC
-TC_ERM_BV_23_C         INC
-TC_ERM_BI_01_C         INC
-TC_ERM_BI_02_C         INC
-TC_ERM_BI_03_C         INC
-TC_ERM_BI_04_C         INC
-TC_ERM_BI_05_C         INC
+TC_ERM_BV_20_C         PASS
+TC_ERM_BV_21_C         PASS
+TC_ERM_BV_22_C         PASS
+TC_ERM_BV_23_C         PASS
+TC_ERM_BI_01_C         PASS
+TC_ERM_BI_02_C         PASS
+TC_ERM_BI_03_C         PASS
+TC_ERM_BI_04_C         PASS
+TC_ERM_BI_05_C         PASS
 TC_STM_BV_01_C         INC
 TC_STM_BV_02_C         INC
 TC_STM_BV_03_C         INC
 TC_STM_BV_11_C         N/A
 TC_STM_BV_12_C         N/A
 TC_STM_BV_13_C         N/A
-TC_FIX_BV_01_C         PASS
-TC_FIX_BV_02_C         PASS
+TC_FIX_BV_01_C         PASS    l2test -n -P 33 <bdaddr>
+TC_FIX_BV_02_C         N/A
 TC_EWC_BV_01_C         N/A
 TC_EWC_BV_02_C         N/A
 TC_EWC_BV_03_C         N/A
-- 
1.8.3.2

---------------------------------------------------------------------
Intel Finland Oy
Registered Address: PL 281, 00181 Helsinki 
Business Identity Code: 0357606 - 4 
Domiciled in Helsinki 

This e-mail and any attachments may contain confidential material for
the sole use of the intended recipient(s). Any review or distribution
by others is strictly prohibited. If you are not the intended
recipient, please contact the sender and delete all copies.


^ permalink raw reply related

* Re: [PATCH_v4 0/4] Add support for NAP role
From: Szymon Janc @ 2014-01-10 11:34 UTC (permalink / raw)
  To: Ravi kumar Veeramally; +Cc: linux-bluetooth
In-Reply-To: <1389181593-9683-1-git-send-email-ravikumar.veeramally@linux.intel.com>

Hi Ravi,

On Wednesday 08 of January 2014 13:46:29 Ravi kumar Veeramally wrote:
> v4: Fixed Szymon's and Luiz's comments.
> 
> v3: Fixed Johan's comments (removed fopen, fprintf and used open and write).
> 
> v2: Fixed Johan's comments.
> 
> v1: This patch set add support for NAP role. It register NAP server and create
>   bnep bridge and listen for incoming connections from client devices.
>   On incoming connection request it accepts connection, creates bnep interface
>   and notifies control state and connection state infromation. Removes device
>   on disconnect request. Android related changes are required to enable this
>   role. Patches sent to respective ML.
> 
> Ravi kumar Veeramally (4):
>   android/pan: Register Network Access Point
>   android/pan: Listen for incoming connections and accept in NAP role
>   android/pan: Implement PAN enable HAL api at daemon side
>   android/pan: Remove connected PAN devices on profile unregister call
> 
>  android/pan.c | 346 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++--
>  1 file changed, 334 insertions(+), 12 deletions(-)

For the records, please fix issues pointed on IRC and resend.

-- 
Best regards, 
Szymon Janc

^ permalink raw reply

* Re: [PATCH v2] android/tester: Multi property check for test case
From: Marcin Kraglak @ 2014-01-10 11:06 UTC (permalink / raw)
  To: Grzegorz Kolodziejczyk; +Cc: linux-bluetooth@vger.kernel.org development
In-Reply-To: <1389345774-3824-1-git-send-email-grzegorz.kolodziejczyk@tieto.com>

Hi Grzegorz,

On 10 January 2014 10:22, Grzegorz Kolodziejczyk
<grzegorz.kolodziejczyk@tieto.com> wrote:
> This patch allows to check multiple properties for test case. Properties
> can be prioritized to allow check if they'll come in right order. Now
> properties aren't treated as a "single" callback. In future in one
> callback multiple properties can come.
> ---
>  android/android-tester.c | 530 ++++++++++++++++++++++++++++++++++-------------
>  1 file changed, 386 insertions(+), 144 deletions(-)
>
> diff --git a/android/android-tester.c b/android/android-tester.c
> index a29c982..a3c5f58 100644
> --- a/android/android-tester.c
> +++ b/android/android-tester.c
> @@ -43,13 +43,19 @@
>
>  #include "utils.h"
>
> +struct priority_property {
> +       bt_property_t prop;
> +       int prio;
> +};
> +
>  struct generic_data {
>         int expected_adapter_status;
>         uint32_t expect_settings_set;
>         int expected_cb_count;
>         bt_property_t set_property;
> -       bt_property_t expected_property;
>         bt_callbacks_t expected_hal_cb;
> +       struct priority_property *expected_properties;
> +       uint8_t expected_properties_num;
>  };
>
>  struct socket_data {
> @@ -91,6 +97,7 @@ struct test_data {
>         bool test_init_done;
>
>         int cb_count;
> +       GSList *expected_properties_list;
>  };
>
>  static char exec_dir[PATH_MAX + 1];
> @@ -185,9 +192,18 @@ static void expected_status_init(struct test_data *data)
>  static void test_property_init(struct test_data *data)
>  {
>         const struct generic_data *test_data = data->test_data;
> +       GSList *l = data->expected_properties_list;
> +       int i;
>
> -       if (!test_data->expected_property.type)
> +       if (!test_data->expected_hal_cb.adapter_properties_cb) {
>                 data->property_checked = true;
> +               return;
> +       }
> +
> +       for (i = 0; i < test_data->expected_properties_num; i++)
> +               l = g_slist_prepend(l, &(test_data->expected_properties[i]));
> +
> +       data->expected_properties_list = l;
>  }
>
>  static void init_test_conditions(struct test_data *data)
> @@ -212,6 +228,75 @@ static void check_expected_status(uint8_t status)
>                 tester_test_failed();
>  }
>
> +static int locate_property(gconstpointer expected_data,
> +                                               gconstpointer received_prop)
> +{
> +       bt_property_t rec_prop = *((bt_property_t *)received_prop);
> +       bt_property_t exp_prop =
> +                       ((struct priority_property *)expected_data)->prop;
> +
> +       if (exp_prop.type && (exp_prop.type != rec_prop.type))
> +               return 1;
> +       if (exp_prop.len && (exp_prop.len != rec_prop.len))
> +               return 1;
> +       if (exp_prop.val && memcmp(exp_prop.val, rec_prop.val, exp_prop.len))
> +               return 1;
> +
> +       return 0;
> +}
> +
> +static int compare_priorities(gconstpointer prop_list, gconstpointer priority)
> +{
> +       int prio = GPOINTER_TO_INT(priority);
> +       int comp_prio = ((struct priority_property *)prop_list)->prio;
> +
> +       if (prio > comp_prio)
> +               return 0;
> +
> +       return 1;
> +}
> +
> +static bool check_prop_priority(int rec_prop_prio)
> +{
> +       struct test_data *data = tester_get_data();
> +       GSList *l = data->expected_properties_list;
> +
> +       if (!rec_prop_prio || !g_slist_length(l))
> +               return true;
> +
> +       if (g_slist_find_custom(l, GINT_TO_POINTER(rec_prop_prio),
> +                                                       &compare_priorities))
> +               return false;
> +
> +       return true;
> +}
> +
> +static void check_expected_property(bt_property_t received_prop)
> +{
> +       struct test_data *data = tester_get_data();
> +       int rec_prio;
> +       GSList *l = data->expected_properties_list;
> +       GSList *found_exp_prop;
> +
> +       found_exp_prop = g_slist_find_custom(l, &received_prop,
> +                                                       &locate_property);
> +
> +       if (found_exp_prop) {
> +               rec_prio = ((struct priority_property *)
> +                                               (found_exp_prop->data))->prio;
> +               if (check_prop_priority(rec_prio))
> +                       l = g_slist_remove(l, found_exp_prop->data);
> +       }
> +
> +       data->expected_properties_list = l;
> +
> +       if (g_slist_length(l))
> +               return;
> +
> +       data->property_checked = true;
> +       test_update_state();
> +}
> +
>  static bool check_test_property(bt_property_t received_prop,
>                                                 bt_property_t expected_prop)
>  {
> @@ -625,27 +710,18 @@ static void device_found_cb(int num_properties, bt_property_t *properties)
>         if (data->test_init_done && test->expected_hal_cb.device_found_cb) {
>                 test->expected_hal_cb.device_found_cb(num_properties,
>                                                                 properties);
> -               check_cb_count();
>         }
>  }
>
>  static void check_count_properties_cb(bt_status_t status, int num_properties,
>                                                 bt_property_t *properties)
>  {
> -       struct test_data *data = tester_get_data();
> +       int i;
>
> -       data->cb_count--;
> +       for (i = 0; i < num_properties; i++)
> +               check_expected_property(properties[i]);
>  }
>
> -static void getprop_success_cb(bt_status_t status, int num_properties,
> -                                               bt_property_t *properties)
> -{
> -       struct test_data *data = tester_get_data();
> -       const struct generic_data *test = data->test_data;
> -
> -       if (check_test_property(properties[0], test->expected_property))
> -               data->cb_count--;
> -}
>
>  static void adapter_properties_cb(bt_status_t status, int num_properties,
>                                                 bt_property_t *properties)
> @@ -658,21 +734,87 @@ static void adapter_properties_cb(bt_status_t status, int num_properties,
>                 test->expected_hal_cb.adapter_properties_cb(
>                                                         status, num_properties,
>                                                         properties);
> -               check_cb_count();
>         }
>  }
>

I think you should fetch bdaddr from hciemu, not hardcode it
> +static bt_bdaddr_t enable_done_bdaddr_val = {
> +       .address = { 0x00, 0xaa, 0x01, 0x00, 0x00, 0x00 },
> +};
> +static const char enable_done_bdname_val[] = "";
> +static bt_uuid_t enable_done_uuids_val = {
> +       .uu = { 0x00, 0x00, 0x12, 0x00, 0x00, 0x00, 0x10, 0x00, 0x80, 0x00,
> +                                       0x00, 0x80, 0x5f, 0x9b, 0x34, 0xfb},
> +};
> +static uint32_t enable_done_cod_val = 0;
> +static bt_device_type_t enable_done_tod_val = BT_DEVICE_DEVTYPE_BREDR;
> +static bt_scan_mode_t enable_done_scanmode_val = BT_SCAN_MODE_NONE;
> +static uint32_t enable_done_disctimeout_val = 120;
> +
> +static struct priority_property enable_done_props[] = {
> +       {
> +       .prop.type = BT_PROPERTY_BDADDR,
> +       .prop.len = sizeof(enable_done_bdaddr_val),
> +       .prop.val = &enable_done_bdaddr_val,
> +       .prio = 1,
> +       },
> +       {
> +       .prop.type = BT_PROPERTY_BDNAME,
> +       .prop.len = sizeof(enable_done_bdname_val) - 1,
> +       .prop.val = &enable_done_bdname_val,
> +       .prio = 2,
> +       },
> +       {
> +       .prop.type = BT_PROPERTY_UUIDS,
> +       .prop.len = sizeof(enable_done_uuids_val),
> +       .prop.val = &enable_done_uuids_val,
> +       .prio = 3,
> +       },
> +       {
> +       .prop.type = BT_PROPERTY_CLASS_OF_DEVICE,
> +       .prop.len = sizeof(enable_done_cod_val),
> +       .prop.val = &enable_done_cod_val,
> +       .prio = 4,
> +       },
> +       {
> +       .prop.type = BT_PROPERTY_TYPE_OF_DEVICE,
> +       .prop.len = sizeof(enable_done_tod_val),
> +       .prop.val = &enable_done_tod_val,
> +       .prio = 5,
> +       },
> +       {
> +       .prop.type = BT_PROPERTY_ADAPTER_SCAN_MODE,
> +       .prop.len = sizeof(enable_done_scanmode_val),
> +       .prop.val = &enable_done_scanmode_val,
> +       .prio = 6,
> +       },
> +       {
> +       .prop.type = BT_PROPERTY_ADAPTER_BONDED_DEVICES,
> +       .prop.len = 0,
> +       .prop.val = NULL,
> +       .prio = 7,
> +       },
> +       {
> +       .prop.type = BT_PROPERTY_ADAPTER_DISCOVERY_TIMEOUT,
> +       .prop.len = sizeof(enable_done_disctimeout_val),
> +       .prop.val = &enable_done_disctimeout_val,
> +       .prio = 8,
> +       },
> +};
> +
>  static const struct generic_data bluetooth_enable_success_test = {
>         .expected_hal_cb.adapter_state_changed_cb = enable_success_cb,
>         .expected_hal_cb.adapter_properties_cb = check_count_properties_cb,
> -       .expected_cb_count = 9,
> +       .expected_cb_count = 1,
> +       .expected_properties_num = 8,
> +       .expected_properties = enable_done_props,
>         .expected_adapter_status = BT_STATUS_SUCCESS,
>  };
>
>  static const struct generic_data bluetooth_enable_done_test = {
>         .expected_hal_cb.adapter_properties_cb = check_count_properties_cb,
> -       .expected_cb_count = 8,
>         .expected_adapter_status = BT_STATUS_DONE,
> +       .expected_properties_num = 8,
> +       .expected_properties = enable_done_props,
>  };
>
>  static const struct generic_data bluetooth_disable_success_test = {
> @@ -683,94 +825,148 @@ static const struct generic_data bluetooth_disable_success_test = {
>
>  static char test_set_bdname[] = "test_bdname_set";
>
> +static struct priority_property setprop_bdname_props[] = {
> +       {
> +       .prop.type = BT_PROPERTY_BDNAME,
> +       .prop.val = test_set_bdname,
> +       .prop.len = sizeof(test_set_bdname) - 1,
> +       .prio = 0,
> +       },
> +};
> +
>  static const struct generic_data bluetooth_setprop_bdname_success_test = {
> -       .expected_hal_cb.adapter_properties_cb = getprop_success_cb,
> -       .expected_cb_count = 1,
> -       .expected_adapter_status = BT_STATUS_SUCCESS,
> -       .expected_property.type = BT_PROPERTY_BDNAME,
> -       .expected_property.val = test_set_bdname,
> -       .expected_property.len = sizeof(test_set_bdname) - 1,
> +       .expected_hal_cb.adapter_properties_cb = check_count_properties_cb,
> +       .expected_properties_num = 1,
> +       .expected_properties = setprop_bdname_props,
>  };
>
>  static bt_scan_mode_t test_setprop_scanmode_val =
>                                         BT_SCAN_MODE_CONNECTABLE_DISCOVERABLE;
>
> +static struct priority_property setprop_scanmode_props[] = {
> +       {
> +       .prop.type = BT_PROPERTY_ADAPTER_SCAN_MODE,
> +       .prop.val = &test_setprop_scanmode_val,
> +       .prop.len = sizeof(bt_scan_mode_t),
> +       },
> +};
> +
>  static const struct generic_data bluetooth_setprop_scanmode_success_test = {
> -       .expected_hal_cb.adapter_properties_cb = getprop_success_cb,
> -       .expected_cb_count = 1,
> +       .expected_hal_cb.adapter_properties_cb = check_count_properties_cb,
> +       .expected_properties_num = 1,
> +       .expected_properties = setprop_scanmode_props,
>         .expected_adapter_status = BT_STATUS_SUCCESS,
> -       .expected_property.type = BT_PROPERTY_ADAPTER_SCAN_MODE,
> -       .expected_property.val = &test_setprop_scanmode_val,
> -       .expected_property.len = sizeof(bt_scan_mode_t),
>  };
>
>  static uint32_t test_setprop_disctimeout_val = 120;
>
> +static struct priority_property setprop_disctimeout_props[] = {
> +       {
> +       .prop.type = BT_PROPERTY_ADAPTER_DISCOVERY_TIMEOUT,
> +       .prop.val = &test_setprop_disctimeout_val,
> +       .prop.len = sizeof(test_setprop_disctimeout_val),
> +       },
> +};
> +
>  static const struct generic_data bluetooth_setprop_disctimeout_success_test = {
> -       .expected_hal_cb.adapter_properties_cb = getprop_success_cb,
> -       .expected_cb_count = 1,
> +       .expected_hal_cb.adapter_properties_cb = check_count_properties_cb,
> +       .expected_properties_num = 1,
> +       .expected_properties = setprop_disctimeout_props,
>         .expected_adapter_status = BT_STATUS_SUCCESS,
> -       .expected_property.type = BT_PROPERTY_ADAPTER_DISCOVERY_TIMEOUT,
> -       .expected_property.val = &test_setprop_disctimeout_val,
> -       .expected_property.len = sizeof(test_setprop_disctimeout_val),
> +};
> +
> +static bt_bdaddr_t test_getprop_bdaddr_val = {
> +       .address = { 0x00, 0xaa, 0x01, 0x00, 0x00, 0x00 }
> +};
> +
> +static struct priority_property getprop_bdaddr_props[] = {
> +       {
> +       .prop.type = BT_PROPERTY_BDADDR,
> +       .prop.val = &test_getprop_bdaddr_val,
> +       .prop.len = sizeof(test_getprop_bdaddr_val),
> +       },
>  };
>
>  static const struct generic_data bluetooth_getprop_bdaddr_success_test = {
> -       .expected_hal_cb.adapter_properties_cb = getprop_success_cb,
> -       .expected_cb_count = 1,
> +       .expected_hal_cb.adapter_properties_cb = check_count_properties_cb,
> +       .expected_properties_num = 1,
> +       .expected_properties = getprop_bdaddr_props,
>         .expected_adapter_status = BT_STATUS_SUCCESS,
> -       .expected_property.type = BT_PROPERTY_BDADDR,
> -       .expected_property.val = NULL,
> -       .expected_property.len = sizeof(bt_bdaddr_t),
>  };
>
>  static char test_bdname[] = "test_bdname_setget";
>
> +static struct priority_property getprop_bdname_props[] = {
> +       {
> +       .prop.type = BT_PROPERTY_BDNAME,
> +       .prop.val = &test_bdname,
> +       .prop.len = sizeof(test_bdname) - 1,
> +       },
> +};
> +
>  static const struct generic_data bluetooth_getprop_bdname_success_test = {
> -       .expected_hal_cb.adapter_properties_cb = getprop_success_cb,
> -       .expected_cb_count = 1,
> +       .expected_hal_cb.adapter_properties_cb = check_count_properties_cb,
> +       .expected_properties_num = 1,
> +       .expected_properties = getprop_bdname_props,
>         .expected_adapter_status = BT_STATUS_SUCCESS,
> -       .expected_property.type = BT_PROPERTY_BDNAME,
> -       .expected_property.val = test_bdname,
> -       .expected_property.len = sizeof(test_bdname) - 1,
>  };
>
>  static unsigned char setprop_uuids[] = { 0xfb, 0x34, 0x9b, 0x5f, 0x80, 0x00,
>                         0x00, 0x80, 0x00, 0x10, 0x00, 0x00, 0x00, 0x00, 0x00,
>                         0x00, 0x00 };
>
> +static struct priority_property setprop_uuid_prop[] = {
> +       {
> +       .prop.type = BT_PROPERTY_UUIDS,
> +       .prop.val = &setprop_uuids,
> +       .prop.len = sizeof(setprop_uuids),
> +       },
> +};
> +
>  static const struct generic_data bluetooth_setprop_uuid_invalid_test = {
>         .expected_adapter_status = BT_STATUS_FAIL,
> -       .set_property.type = BT_PROPERTY_UUIDS,
> -       .set_property.val = &setprop_uuids,
> -       .set_property.len = sizeof(setprop_uuids),
>  };
>
>  static uint32_t setprop_class_of_device = 0;
>
> +static struct priority_property setprop_cod_props[] = {
> +       {
> +       .prop.type = BT_PROPERTY_CLASS_OF_DEVICE,
> +       .prop.val = &setprop_class_of_device,
> +       .prop.len = sizeof(setprop_class_of_device),
> +       },
> +};
> +
>  static const struct generic_data bluetooth_setprop_cod_invalid_test = {
>         .expected_adapter_status = BT_STATUS_FAIL,
> -       .set_property.type = BT_PROPERTY_CLASS_OF_DEVICE,
> -       .set_property.val = &setprop_class_of_device,
> -       .set_property.len = sizeof(setprop_class_of_device),
>  };
>
>  static bt_device_type_t setprop_type_of_device = BT_DEVICE_DEVTYPE_BREDR;
>
> +static struct priority_property setprop_tod_props[] = {
> +       {
> +       .prop.type = BT_PROPERTY_TYPE_OF_DEVICE,
> +       .prop.val = &setprop_type_of_device,
> +       .prop.len = sizeof(setprop_type_of_device),
> +       },
> +};
> +
>  static const struct generic_data bluetooth_setprop_tod_invalid_test = {
>         .expected_adapter_status = BT_STATUS_FAIL,
> -       .set_property.type = BT_PROPERTY_TYPE_OF_DEVICE,
> -       .set_property.val = &setprop_type_of_device,
> -       .set_property.len = sizeof(setprop_type_of_device),
>  };
>
>  static int32_t setprop_remote_rssi = 0;
>
> +static struct priority_property setprop_remote_rssi_props[] = {
> +       {
> +       .prop.type = BT_PROPERTY_REMOTE_RSSI,
> +       .prop.val = &setprop_remote_rssi,
> +       .prop.len = sizeof(setprop_remote_rssi),
> +       },
> +};
> +
>  static const struct generic_data bluetooth_setprop_remote_rssi_invalid_test = {
>         .expected_adapter_status = BT_STATUS_FAIL,
> -       .set_property.type = BT_PROPERTY_REMOTE_RSSI,
> -       .set_property.val = &setprop_remote_rssi,
> -       .set_property.len = sizeof(setprop_remote_rssi),
>  };
>
>  static bt_service_record_t setprop_remote_service = {
> @@ -779,91 +975,136 @@ static bt_service_record_t setprop_remote_service = {
>         .name = "bt_name",
>  };
>
> +static struct priority_property setprop_service_record_props[] = {
> +       {
> +       .prop.type = BT_PROPERTY_SERVICE_RECORD,
> +       .prop.val = &setprop_remote_service,
> +       .prop.len = sizeof(setprop_remote_service),
> +       },
> +};
> +
>  static const struct generic_data
>                         bluetooth_setprop_service_record_invalid_test = {
>         .expected_adapter_status = BT_STATUS_FAIL,
> -       .set_property.type = BT_PROPERTY_SERVICE_RECORD,
> -       .set_property.val = &setprop_remote_service,
> -       .set_property.len = sizeof(setprop_remote_service),
>  };
>
>  static bt_bdaddr_t setprop_bdaddr = {
>         .address = { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 },
>  };
>
> +static struct priority_property setprop_bdaddr_props[] = {
> +       {
> +       .prop.type = BT_PROPERTY_BDADDR,
> +       .prop.val = &setprop_bdaddr,
> +       .prop.len = sizeof(setprop_bdaddr),
> +       },
> +};
> +
>  static const struct generic_data bluetooth_setprop_bdaddr_invalid_test = {
>         .expected_adapter_status = BT_STATUS_FAIL,
> -       .set_property.type = BT_PROPERTY_BDADDR,
> -       .set_property.val = &setprop_bdaddr,
> -       .set_property.len = sizeof(setprop_bdaddr),
>  };
>
>  static bt_scan_mode_t setprop_scanmode_connectable = BT_SCAN_MODE_CONNECTABLE;
>
> +static struct priority_property setprop_scanmode_connectable_props[] = {
> +       {
> +       .prop.type = BT_PROPERTY_ADAPTER_SCAN_MODE,
> +       .prop.val = &setprop_scanmode_connectable,
> +       .prop.len = sizeof(setprop_scanmode_connectable),
> +       },
> +};
> +
>  static const struct generic_data
>                         bluetooth_setprop_scanmode_connectable_success_test = {
> -       .expected_hal_cb.adapter_properties_cb = getprop_success_cb,
> -       .expected_cb_count = 1,
> +       .expected_hal_cb.adapter_properties_cb = check_count_properties_cb,
> +       .expected_properties_num = 1,
> +       .expected_properties = setprop_scanmode_connectable_props,
>         .expected_adapter_status = BT_STATUS_SUCCESS,
> -       .expected_property.type = BT_PROPERTY_ADAPTER_SCAN_MODE,
> -       .expected_property.val = &setprop_scanmode_connectable,
> -       .expected_property.len = sizeof(setprop_scanmode_connectable),
>  };
>
>  static bt_bdaddr_t setprop_bonded_devices = {
>         .address = { 0x00, 0x01, 0x02, 0x03, 0x04, 0x05 },
>  };
>
> +static struct priority_property setprop_bonded_devices_props[] = {
> +       {
> +       .prop.type = BT_PROPERTY_ADAPTER_BONDED_DEVICES,
> +       .prop.val = &setprop_bonded_devices,
> +       .prop.len = sizeof(setprop_bonded_devices),
> +       },
> +};
> +
>  static const struct generic_data
>                         bluetooth_setprop_bonded_devices_invalid_test = {
>         .expected_adapter_status = BT_STATUS_FAIL,
> -       .set_property.type = BT_PROPERTY_ADAPTER_BONDED_DEVICES,
> -       .set_property.val = &setprop_bonded_devices,
> -       .set_property.len = sizeof(setprop_bonded_devices),
>  };
>
>  static uint32_t getprop_cod = 0;
>
> +static struct priority_property getprop_cod_props[] = {
> +       {
> +       .prop.type = BT_PROPERTY_CLASS_OF_DEVICE,
> +       .prop.val = &getprop_cod,
> +       .prop.len = sizeof(getprop_cod),
> +       },
> +};
> +
>  static const struct generic_data bluetooth_getprop_cod_success_test = {
> -       .expected_hal_cb.adapter_properties_cb = getprop_success_cb,
> -       .expected_cb_count = 1,
> +       .expected_hal_cb.adapter_properties_cb = check_count_properties_cb,
> +       .expected_properties_num = 1,
> +       .expected_properties = getprop_cod_props,
>         .expected_adapter_status = BT_STATUS_SUCCESS,
> -       .expected_property.type = BT_PROPERTY_CLASS_OF_DEVICE,
> -       .expected_property.val = &getprop_cod,
> -       .expected_property.len = sizeof(getprop_cod),
>  };
>
>  static bt_device_type_t getprop_tod = BT_DEVICE_DEVTYPE_BREDR;
>
> +static struct priority_property getprop_tod_props[] = {
> +       {
> +       .prop.type = BT_PROPERTY_TYPE_OF_DEVICE,
> +       .prop.val = &getprop_tod,
> +       .prop.len = sizeof(getprop_tod),
> +       },
> +};
> +
>  static const struct generic_data bluetooth_getprop_tod_success_test = {
> -       .expected_hal_cb.adapter_properties_cb = getprop_success_cb,
> -       .expected_cb_count = 1,
> +       .expected_hal_cb.adapter_properties_cb = check_count_properties_cb,
> +       .expected_properties_num = 1,
> +       .expected_properties = getprop_tod_props,
>         .expected_adapter_status = BT_STATUS_SUCCESS,
> -       .expected_property.type = BT_PROPERTY_TYPE_OF_DEVICE,
> -       .expected_property.val = &getprop_tod,
> -       .expected_property.len = sizeof(getprop_tod),
>  };
>
>  static bt_scan_mode_t getprop_scanmode = BT_SCAN_MODE_NONE;
>
> +static struct priority_property getprop_scanmode_props[] = {
> +       {
> +       .prop.type = BT_PROPERTY_ADAPTER_SCAN_MODE,
> +       .prop.val = &getprop_scanmode,
> +       .prop.len = sizeof(getprop_scanmode),
> +       },
> +};
> +
>  static const struct generic_data bluetooth_getprop_scanmode_success_test = {
> -       .expected_hal_cb.adapter_properties_cb = getprop_success_cb,
> -       .expected_cb_count = 1,
> +       .expected_hal_cb.adapter_properties_cb = check_count_properties_cb,
> +       .expected_properties_num = 1,
> +       .expected_properties = getprop_scanmode_props,
>         .expected_adapter_status = BT_STATUS_SUCCESS,
> -       .expected_property.type = BT_PROPERTY_ADAPTER_SCAN_MODE,
> -       .expected_property.val = &getprop_scanmode,
> -       .expected_property.len = sizeof(getprop_scanmode),
>  };
>
>  static uint32_t getprop_disctimeout_val = 120;
>
> +static struct priority_property getprop_disctimeout_props[] = {
> +       {
> +       .prop.type = BT_PROPERTY_ADAPTER_DISCOVERY_TIMEOUT,
> +       .prop.val = &getprop_disctimeout_val,
> +       .prop.len = sizeof(getprop_disctimeout_val),
> +       },
> +};
> +
>  static const struct generic_data bluetooth_getprop_disctimeout_success_test = {
> -       .expected_hal_cb.adapter_properties_cb = getprop_success_cb,
> -       .expected_cb_count = 1,
> +       .expected_hal_cb.adapter_properties_cb = check_count_properties_cb,
> +       .expected_properties_num = 1,
> +       .expected_properties = getprop_disctimeout_props,
>         .expected_adapter_status = BT_STATUS_SUCCESS,
> -       .expected_property.type = BT_PROPERTY_ADAPTER_DISCOVERY_TIMEOUT,
> -       .expected_property.val = &getprop_disctimeout_val,
> -       .expected_property.len = sizeof(getprop_disctimeout_val),
>  };
>
>  static bt_uuid_t getprop_uuids = {
> @@ -871,33 +1112,51 @@ static bt_uuid_t getprop_uuids = {
>                                         0x00, 0x80, 0x5F, 0x9B, 0x34, 0xFB },
>  };
>
> +static struct priority_property getprop_uuids_props[] = {
> +       {
> +       .prop.type = BT_PROPERTY_UUIDS,
> +       .prop.val = &getprop_uuids,
> +       .prop.len = sizeof(getprop_uuids),
> +       },
> +};
> +
>  static const struct generic_data bluetooth_getprop_uuids_success_test = {
> -       .expected_hal_cb.adapter_properties_cb = getprop_success_cb,
> -       .expected_cb_count = 1,
> +       .expected_hal_cb.adapter_properties_cb = check_count_properties_cb,
> +       .expected_properties_num = 1,
> +       .expected_properties = getprop_uuids_props,
>         .expected_adapter_status = BT_STATUS_SUCCESS,
> -       .expected_property.type = BT_PROPERTY_UUIDS,
> -       .expected_property.val = &getprop_uuids,
> -       .expected_property.len = sizeof(getprop_uuids),
> +};
> +
> +static struct priority_property getprop_bondeddev_props[] = {
> +       {
> +       .prop.type = BT_PROPERTY_ADAPTER_BONDED_DEVICES,
> +       .prop.val = NULL,
> +       .prop.len = 0,
> +       },
>  };
>
>  static const struct generic_data bluetooth_getprop_bondeddev_success_test = {
> -       .expected_hal_cb.adapter_properties_cb = getprop_success_cb,
> -       .expected_cb_count = 1,
> +       .expected_hal_cb.adapter_properties_cb = check_count_properties_cb,
> +       .expected_properties_num = 1,
> +       .expected_properties = getprop_bondeddev_props,
>         .expected_adapter_status = BT_STATUS_SUCCESS,
> -       .expected_property.type = BT_PROPERTY_ADAPTER_BONDED_DEVICES,
> -       .expected_property.val = NULL,
> -       .expected_property.len = 0,
>  };
>
>  static bt_scan_mode_t setprop_scanmode_none = BT_SCAN_MODE_NONE;
>
> +static struct priority_property setprop_scanmode_none_props[] = {
> +       {
> +       .prop.type = BT_PROPERTY_ADAPTER_SCAN_MODE,
> +       .prop.val = &setprop_scanmode_none,
> +       .prop.len = sizeof(setprop_scanmode_none),
> +       },
> +};
> +
>  static const struct generic_data bluetooth_setprop_scanmode_none_done_test = {
> -       .expected_hal_cb.adapter_properties_cb = getprop_success_cb,
> -       .expected_cb_count = 1,
> +       .expected_hal_cb.adapter_properties_cb = check_count_properties_cb,
> +       .expected_properties_num = 1,
> +       .expected_properties = setprop_scanmode_none_props,
>         .expected_adapter_status = BT_STATUS_DONE,
> -       .expected_property.type = BT_PROPERTY_ADAPTER_SCAN_MODE,
> -       .expected_property.val = &setprop_scanmode_none,
> -       .expected_property.len = sizeof(setprop_scanmode_none),
>  };
>
>  static const struct generic_data bluetooth_discovery_start_success_test = {
> @@ -1073,6 +1332,9 @@ static void teardown(const void *test_data)
>                 data->if_bluetooth = NULL;
>         }
>
> +       if (data->expected_properties_list)
> +               g_slist_free(data->expected_properties_list);
> +
>         data->device->close(data->device);
>
>         if (data->bluetoothd_pid)
> @@ -1122,22 +1384,19 @@ static void test_disable(const void *test_data)
>  static void test_setprop_bdname_success(const void *test_data)
>  {
>         struct test_data *data = tester_get_data();
> -       const struct generic_data *test = data->test_data;
> -       const bt_property_t *prop = &test->expected_property;
> +       const bt_property_t *prop = &(setprop_bdname_props[0].prop);
>         bt_status_t adapter_status;
>
>         init_test_conditions(data);
>
>         adapter_status = data->if_bluetooth->set_adapter_property(prop);
> -
>         check_expected_status(adapter_status);
>  }
>
>  static void test_setprop_scanmode_succes(const void *test_data)
>  {
>         struct test_data *data = tester_get_data();
> -       const struct generic_data *test = data->test_data;
> -       const bt_property_t *prop = &test->expected_property;
> +       const bt_property_t *prop = &(setprop_scanmode_props[0].prop);
>         bt_status_t adapter_status;
>
>         init_test_conditions(data);
> @@ -1149,8 +1408,7 @@ static void test_setprop_scanmode_succes(const void *test_data)
>  static void test_setprop_disctimeout_succes(const void *test_data)
>  {
>         struct test_data *data = tester_get_data();
> -       const struct generic_data *test = data->test_data;
> -       const bt_property_t *prop = &test->expected_property;
> +       const bt_property_t *prop = &(setprop_disctimeout_props[0].prop);
>         bt_status_t adapter_status;
>
>         init_test_conditions(data);
> @@ -1162,8 +1420,7 @@ static void test_setprop_disctimeout_succes(const void *test_data)
>  static void test_getprop_bdaddr_success(const void *test_data)
>  {
>         struct test_data *data = tester_get_data();
> -       const struct generic_data *test = data->test_data;
> -       const bt_property_t prop = test->expected_property;
> +       const bt_property_t prop = setprop_bdaddr_props[0].prop;
>         bt_status_t adapter_status;
>
>         init_test_conditions(data);
> @@ -1175,8 +1432,7 @@ static void test_getprop_bdaddr_success(const void *test_data)
>  static void test_getprop_bdname_success(const void *test_data)
>  {
>         struct test_data *data = tester_get_data();
> -       const struct generic_data *test = data->test_data;
> -       const bt_property_t *prop = &test->expected_property;
> +       const bt_property_t *prop = &(getprop_bdname_props[0].prop);
>         bt_status_t adapter_status;
>
>         init_test_conditions(data);
> @@ -1187,12 +1443,10 @@ static void test_getprop_bdname_success(const void *test_data)
>         adapter_status = data->if_bluetooth->get_adapter_property((*prop).type);
>         check_expected_status(adapter_status);
>  }
> -
>  static void test_setprop_uuid_invalid(const void *test_data)
>  {
>         struct test_data *data = tester_get_data();
> -       const struct generic_data *test = data->test_data;
> -       const bt_property_t *prop = &test->expected_property;
> +       const bt_property_t *prop = &(setprop_uuid_prop[0].prop);
>         bt_status_t adapter_status;
>
>         init_test_conditions(data);
> @@ -1204,8 +1458,7 @@ static void test_setprop_uuid_invalid(const void *test_data)
>  static void test_setprop_cod_invalid(const void *test_data)
>  {
>         struct test_data *data = tester_get_data();
> -       const struct generic_data *test = data->test_data;
> -       const bt_property_t *prop = &test->expected_property;
> +       const bt_property_t *prop = &(setprop_cod_props[0].prop);
>         bt_status_t adapter_status;
>
>         init_test_conditions(data);
> @@ -1230,8 +1483,7 @@ static void test_setprop_tod_invalid(const void *test_data)
>  static void test_setprop_rssi_invalid(const void *test_data)
>  {
>         struct test_data *data = tester_get_data();
> -       const struct generic_data *test = data->test_data;
> -       const bt_property_t *prop = &test->expected_property;
> +       const bt_property_t *prop = &(setprop_remote_rssi_props[0].prop);
>         bt_status_t adapter_status;
>
>         init_test_conditions(data);
> @@ -1243,8 +1495,7 @@ static void test_setprop_rssi_invalid(const void *test_data)
>  static void test_setprop_service_record_invalid(const void *test_data)
>  {
>         struct test_data *data = tester_get_data();
> -       const struct generic_data *test = data->test_data;
> -       const bt_property_t *prop = &test->expected_property;
> +       const bt_property_t *prop = &(setprop_service_record_props[0].prop);
>         bt_status_t adapter_status;
>
>         init_test_conditions(data);
> @@ -1256,8 +1507,7 @@ static void test_setprop_service_record_invalid(const void *test_data)
>  static void test_setprop_bdaddr_invalid(const void *test_data)
>  {
>         struct test_data *data = tester_get_data();
> -       const struct generic_data *test = data->test_data;
> -       const bt_property_t *prop = &test->expected_property;
> +       const bt_property_t *prop = &(setprop_bdaddr_props[0].prop);
>         bt_status_t adapter_status;
>
>         init_test_conditions(data);
> @@ -1269,8 +1519,8 @@ static void test_setprop_bdaddr_invalid(const void *test_data)
>  static void test_setprop_scanmode_connectable_success(const void *test_data)
>  {
>         struct test_data *data = tester_get_data();
> -       const struct generic_data *test = data->test_data;
> -       const bt_property_t *prop = &test->expected_property;
> +       const bt_property_t *prop =
> +                               &(setprop_scanmode_connectable_props[0].prop);
>         bt_status_t adapter_status;
>
>         init_test_conditions(data);
> @@ -1282,8 +1532,7 @@ static void test_setprop_scanmode_connectable_success(const void *test_data)
>  static void test_setprop_bonded_devices_invalid(const void *test_data)
>  {
>         struct test_data *data = tester_get_data();
> -       const struct generic_data *test = data->test_data;
> -       const bt_property_t *prop = &test->expected_property;
> +       const bt_property_t *prop = &(setprop_bonded_devices_props[0].prop);
>         bt_status_t adapter_status;
>
>         init_test_conditions(data);
> @@ -1295,8 +1544,7 @@ static void test_setprop_bonded_devices_invalid(const void *test_data)
>  static void test_getprop_cod_success(const void *test_data)
>  {
>         struct test_data *data = tester_get_data();
> -       const struct generic_data *test = data->test_data;
> -       const bt_property_t prop = test->expected_property;
> +       const bt_property_t prop = setprop_cod_props[0].prop;
>         bt_status_t adapter_status;
>
>         init_test_conditions(data);
> @@ -1308,8 +1556,7 @@ static void test_getprop_cod_success(const void *test_data)
>  static void test_getprop_tod_success(const void *test_data)
>  {
>         struct test_data *data = tester_get_data();
> -       const struct generic_data *test = data->test_data;
> -       const bt_property_t prop = test->expected_property;
> +       const bt_property_t prop = setprop_tod_props[0].prop;
>         bt_status_t adapter_status;
>
>         init_test_conditions(data);
> @@ -1321,8 +1568,7 @@ static void test_getprop_tod_success(const void *test_data)
>  static void test_getprop_scanmode_success(const void *test_data)
>  {
>         struct test_data *data = tester_get_data();
> -       const struct generic_data *test = data->test_data;
> -       const bt_property_t prop = test->expected_property;
> +       const bt_property_t prop = setprop_scanmode_props[0].prop;
>         bt_status_t adapter_status;
>
>         init_test_conditions(data);
> @@ -1334,8 +1580,7 @@ static void test_getprop_scanmode_success(const void *test_data)
>  static void test_getprop_disctimeout_success(const void *test_data)
>  {
>         struct test_data *data = tester_get_data();
> -       const struct generic_data *test = data->test_data;
> -       const bt_property_t prop = test->expected_property;
> +       const bt_property_t prop = setprop_disctimeout_props[0].prop;
>         bt_status_t adapter_status;
>
>         init_test_conditions(data);
> @@ -1347,8 +1592,7 @@ static void test_getprop_disctimeout_success(const void *test_data)
>  static void test_getprop_uuids_success(const void *test_data)
>  {
>         struct test_data *data = tester_get_data();
> -       const struct generic_data *test = data->test_data;
> -       const bt_property_t prop = test->expected_property;
> +       const bt_property_t prop = getprop_uuids_props[0].prop;
>         bt_status_t adapter_status;
>
>         init_test_conditions(data);
> @@ -1360,8 +1604,7 @@ static void test_getprop_uuids_success(const void *test_data)
>  static void test_getprop_bondeddev_success(const void *test_data)
>  {
>         struct test_data *data = tester_get_data();
> -       const struct generic_data *test = data->test_data;
> -       const bt_property_t prop = test->expected_property;
> +       const bt_property_t prop = getprop_bondeddev_props[0].prop;
>         bt_status_t adapter_status;
>
>         init_test_conditions(data);
> @@ -1373,8 +1616,7 @@ static void test_getprop_bondeddev_success(const void *test_data)
>  static void test_setprop_scanmode_none_done(const void *test_data)
>  {
>         struct test_data *data = tester_get_data();
> -       const struct generic_data *test = data->test_data;
> -       const bt_property_t *prop = &test->expected_property;
> +       const bt_property_t *prop = &(setprop_scanmode_none_props[0].prop);
>         bt_status_t adapter_status;
>
>         init_test_conditions(data);
> --
> 1.8.5.2
>
> --
> To unsubscribe from this list: send the line "unsubscribe linux-bluetooth" in
> the body of a message to majordomo@vger.kernel.org
> More majordomo info at  http://vger.kernel.org/majordomo-info.html

Marcin

^ permalink raw reply

* [PATCH v4 15/15] Bluetooth: Add support for remote OOB input of P-256 data
From: Marcel Holtmann @ 2014-01-10 10:07 UTC (permalink / raw)
  To: linux-bluetooth

The current management interface only allows to provide the remote
OOB input of P-192 data. This extends the command to also accept
P-256 data as well. To make this backwards compatible, the userspace
can decide to only provide P-192 data or the combined P-192 and P-256
data. It is also allowed to leave the P-192 data empty if userspace
only has the remote P-256 data.

Signed-off-by: Marcel Holtmann <marcel@holtmann.org>
---
 include/net/bluetooth/mgmt.h |  8 ++++++++
 net/bluetooth/mgmt.c         | 45 +++++++++++++++++++++++++++++++++-----------
 2 files changed, 42 insertions(+), 11 deletions(-)

diff --git a/include/net/bluetooth/mgmt.h b/include/net/bluetooth/mgmt.h
index 036ddc7dc7ed..e19049fb6c46 100644
--- a/include/net/bluetooth/mgmt.h
+++ b/include/net/bluetooth/mgmt.h
@@ -309,6 +309,14 @@ struct mgmt_cp_add_remote_oob_data {
 	__u8	randomizer[16];
 } __packed;
 #define MGMT_ADD_REMOTE_OOB_DATA_SIZE	(MGMT_ADDR_INFO_SIZE + 32)
+struct mgmt_cp_add_remote_oob_ext_data {
+	struct mgmt_addr_info addr;
+	__u8	hash192[16];
+	__u8	randomizer192[16];
+	__u8	hash256[16];
+	__u8	randomizer256[16];
+} __packed;
+#define MGMT_ADD_REMOTE_OOB_EXT_DATA_SIZE (MGMT_ADDR_INFO_SIZE + 64)
 
 #define MGMT_OP_REMOVE_REMOTE_OOB_DATA	0x0022
 struct mgmt_cp_remove_remote_oob_data {
diff --git a/net/bluetooth/mgmt.c b/net/bluetooth/mgmt.c
index bbe30c983492..4b6034fcc902 100644
--- a/net/bluetooth/mgmt.c
+++ b/net/bluetooth/mgmt.c
@@ -3096,23 +3096,46 @@ unlock:
 static int add_remote_oob_data(struct sock *sk, struct hci_dev *hdev,
 			       void *data, u16 len)
 {
-	struct mgmt_cp_add_remote_oob_data *cp = data;
-	u8 status;
 	int err;
 
 	BT_DBG("%s ", hdev->name);
 
 	hci_dev_lock(hdev);
 
-	err = hci_add_remote_oob_data(hdev, &cp->addr.bdaddr, cp->hash,
-				      cp->randomizer);
-	if (err < 0)
-		status = MGMT_STATUS_FAILED;
-	else
-		status = MGMT_STATUS_SUCCESS;
+	if (len == MGMT_ADD_REMOTE_OOB_DATA_SIZE) {
+		struct mgmt_cp_add_remote_oob_data *cp = data;
+		u8 status;
 
-	err = cmd_complete(sk, hdev->id, MGMT_OP_ADD_REMOTE_OOB_DATA, status,
-			   &cp->addr, sizeof(cp->addr));
+		err = hci_add_remote_oob_data(hdev, &cp->addr.bdaddr,
+					      cp->hash, cp->randomizer);
+		if (err < 0)
+			status = MGMT_STATUS_FAILED;
+		else
+			status = MGMT_STATUS_SUCCESS;
+
+		err = cmd_complete(sk, hdev->id, MGMT_OP_ADD_REMOTE_OOB_DATA,
+				   status, &cp->addr, sizeof(cp->addr));
+	} else if (len == MGMT_ADD_REMOTE_OOB_EXT_DATA_SIZE) {
+		struct mgmt_cp_add_remote_oob_ext_data *cp = data;
+		u8 status;
+
+		err = hci_add_remote_oob_ext_data(hdev, &cp->addr.bdaddr,
+						  cp->hash192,
+						  cp->randomizer192,
+						  cp->hash256,
+						  cp->randomizer256);
+		if (err < 0)
+			status = MGMT_STATUS_FAILED;
+		else
+			status = MGMT_STATUS_SUCCESS;
+
+		err = cmd_complete(sk, hdev->id, MGMT_OP_ADD_REMOTE_OOB_DATA,
+				   status, &cp->addr, sizeof(cp->addr));
+	} else {
+		BT_ERR("add_remote_oob_data: invalid length of %u bytes", len);
+		err = cmd_status(sk, hdev->id, MGMT_OP_ADD_REMOTE_OOB_DATA,
+				 MGMT_STATUS_INVALID_PARAMS);
+	}
 
 	hci_dev_unlock(hdev);
 	return err;
@@ -4202,7 +4225,7 @@ static const struct mgmt_handler {
 	{ user_passkey_reply,     false, MGMT_USER_PASSKEY_REPLY_SIZE },
 	{ user_passkey_neg_reply, false, MGMT_USER_PASSKEY_NEG_REPLY_SIZE },
 	{ read_local_oob_data,    false, MGMT_READ_LOCAL_OOB_DATA_SIZE },
-	{ add_remote_oob_data,    false, MGMT_ADD_REMOTE_OOB_DATA_SIZE },
+	{ add_remote_oob_data,    true,  MGMT_ADD_REMOTE_OOB_DATA_SIZE },
 	{ remove_remote_oob_data, false, MGMT_REMOVE_REMOTE_OOB_DATA_SIZE },
 	{ start_discovery,        false, MGMT_START_DISCOVERY_SIZE },
 	{ stop_discovery,         false, MGMT_STOP_DISCOVERY_SIZE },
-- 
1.8.4.2


^ permalink raw reply related

* [PATCH v4 14/15] Bluetooth: Add internal function for storing P-192 and P-256 data
From: Marcel Holtmann @ 2014-01-10 10:07 UTC (permalink / raw)
  To: linux-bluetooth

Add function to allow adding P-192 and P-256 data to the internal
storage. This also fixes a few coding style issues from the previous
helper functions for the out-of-band credentials storage.

Signed-off-by: Marcel Holtmann <marcel@holtmann.org>
---
 include/net/bluetooth/hci_core.h |  9 ++++++---
 net/bluetooth/hci_core.c         | 37 +++++++++++++++++++++++++++++++++----
 2 files changed, 39 insertions(+), 7 deletions(-)

diff --git a/include/net/bluetooth/hci_core.h b/include/net/bluetooth/hci_core.h
index 5948930f92e6..66e96ebffe97 100644
--- a/include/net/bluetooth/hci_core.h
+++ b/include/net/bluetooth/hci_core.h
@@ -761,9 +761,12 @@ int hci_remove_link_key(struct hci_dev *hdev, bdaddr_t *bdaddr);
 
 int hci_remote_oob_data_clear(struct hci_dev *hdev);
 struct oob_data *hci_find_remote_oob_data(struct hci_dev *hdev,
-							bdaddr_t *bdaddr);
-int hci_add_remote_oob_data(struct hci_dev *hdev, bdaddr_t *bdaddr, u8 *hash,
-								u8 *randomizer);
+					  bdaddr_t *bdaddr);
+int hci_add_remote_oob_data(struct hci_dev *hdev, bdaddr_t *bdaddr,
+			    u8 *hash, u8 *randomizer);
+int hci_add_remote_oob_ext_data(struct hci_dev *hdev, bdaddr_t *bdaddr,
+				u8 *hash192, u8 *randomizer192,
+				u8 *hash256, u8 *randomizer256);
 int hci_remove_remote_oob_data(struct hci_dev *hdev, bdaddr_t *bdaddr);
 
 void hci_event_packet(struct hci_dev *hdev, struct sk_buff *skb);
diff --git a/net/bluetooth/hci_core.c b/net/bluetooth/hci_core.c
index f13c0550f368..499ec1b1095d 100644
--- a/net/bluetooth/hci_core.c
+++ b/net/bluetooth/hci_core.c
@@ -2794,15 +2794,14 @@ int hci_remote_oob_data_clear(struct hci_dev *hdev)
 	return 0;
 }
 
-int hci_add_remote_oob_data(struct hci_dev *hdev, bdaddr_t *bdaddr, u8 *hash,
-			    u8 *randomizer)
+int hci_add_remote_oob_data(struct hci_dev *hdev, bdaddr_t *bdaddr,
+			    u8 *hash, u8 *randomizer)
 {
 	struct oob_data *data;
 
 	data = hci_find_remote_oob_data(hdev, bdaddr);
-
 	if (!data) {
-		data = kzalloc(sizeof(*data), GFP_ATOMIC);
+		data = kmalloc(sizeof(*data), GFP_ATOMIC);
 		if (!data)
 			return -ENOMEM;
 
@@ -2813,6 +2812,36 @@ int hci_add_remote_oob_data(struct hci_dev *hdev, bdaddr_t *bdaddr, u8 *hash,
 	memcpy(data->hash192, hash, sizeof(data->hash192));
 	memcpy(data->randomizer192, randomizer, sizeof(data->randomizer192));
 
+	memset(data->hash256, 0, sizeof(data->hash256));
+	memset(data->randomizer256, 0, sizeof(data->randomizer256));
+
+	BT_DBG("%s for %pMR", hdev->name, bdaddr);
+
+	return 0;
+}
+
+int hci_add_remote_oob_ext_data(struct hci_dev *hdev, bdaddr_t *bdaddr,
+				u8 *hash192, u8 *randomizer192,
+				u8 *hash256, u8 *randomizer256)
+{
+	struct oob_data *data;
+
+	data = hci_find_remote_oob_data(hdev, bdaddr);
+	if (!data) {
+		data = kmalloc(sizeof(*data), GFP_ATOMIC);
+		if (!data)
+			return -ENOMEM;
+
+		bacpy(&data->bdaddr, bdaddr);
+		list_add(&data->list, &hdev->remote_oob_data);
+	}
+
+	memcpy(data->hash192, hash192, sizeof(data->hash192));
+	memcpy(data->randomizer192, randomizer192, sizeof(data->randomizer192));
+
+	memcpy(data->hash256, hash256, sizeof(data->hash256));
+	memcpy(data->randomizer256, randomizer256, sizeof(data->randomizer256));
+
 	BT_DBG("%s for %pMR", hdev->name, bdaddr);
 
 	return 0;
-- 
1.8.4.2


^ permalink raw reply related

* [PATCH v4 13/15] Bluetooth: Provide remote OOB data for Secure Connections
From: Marcel Holtmann @ 2014-01-10 10:07 UTC (permalink / raw)
  To: linux-bluetooth

When Secure Connections has been enabled it is possible to provide P-192
and/or P-256 data during the pairing process. The internal out-of-band
credentials storage has been extended to also hold P-256 data.

Initially the P-256 data will be empty and with Secure Connections enabled
no P-256 data will be provided. This is according to the specification
since it might be possible that the remote side did not provide either
of the out-of-band credentials.

Signed-off-by: Marcel Holtmann <marcel@holtmann.org>
---
 include/net/bluetooth/hci_core.h |  6 ++++--
 net/bluetooth/hci_core.c         |  6 +++---
 net/bluetooth/hci_event.c        | 32 ++++++++++++++++++++++++--------
 3 files changed, 31 insertions(+), 13 deletions(-)

diff --git a/include/net/bluetooth/hci_core.h b/include/net/bluetooth/hci_core.h
index bd15eaa4c06e..5948930f92e6 100644
--- a/include/net/bluetooth/hci_core.h
+++ b/include/net/bluetooth/hci_core.h
@@ -114,8 +114,10 @@ struct link_key {
 struct oob_data {
 	struct list_head list;
 	bdaddr_t bdaddr;
-	u8 hash[16];
-	u8 randomizer[16];
+	u8 hash192[16];
+	u8 randomizer192[16];
+	u8 hash256[16];
+	u8 randomizer256[16];
 };
 
 #define HCI_MAX_SHORT_NAME_LENGTH	10
diff --git a/net/bluetooth/hci_core.c b/net/bluetooth/hci_core.c
index 946631ffe802..f13c0550f368 100644
--- a/net/bluetooth/hci_core.c
+++ b/net/bluetooth/hci_core.c
@@ -2802,7 +2802,7 @@ int hci_add_remote_oob_data(struct hci_dev *hdev, bdaddr_t *bdaddr, u8 *hash,
 	data = hci_find_remote_oob_data(hdev, bdaddr);
 
 	if (!data) {
-		data = kmalloc(sizeof(*data), GFP_ATOMIC);
+		data = kzalloc(sizeof(*data), GFP_ATOMIC);
 		if (!data)
 			return -ENOMEM;
 
@@ -2810,8 +2810,8 @@ int hci_add_remote_oob_data(struct hci_dev *hdev, bdaddr_t *bdaddr, u8 *hash,
 		list_add(&data->list, &hdev->remote_oob_data);
 	}
 
-	memcpy(data->hash, hash, sizeof(data->hash));
-	memcpy(data->randomizer, randomizer, sizeof(data->randomizer));
+	memcpy(data->hash192, hash, sizeof(data->hash192));
+	memcpy(data->randomizer192, randomizer, sizeof(data->randomizer192));
 
 	BT_DBG("%s for %pMR", hdev->name, bdaddr);
 
diff --git a/net/bluetooth/hci_event.c b/net/bluetooth/hci_event.c
index 6923241d2b3e..47b953e24864 100644
--- a/net/bluetooth/hci_event.c
+++ b/net/bluetooth/hci_event.c
@@ -3391,20 +3391,36 @@ static void hci_remote_oob_data_request_evt(struct hci_dev *hdev,
 
 	data = hci_find_remote_oob_data(hdev, &ev->bdaddr);
 	if (data) {
-		struct hci_cp_remote_oob_data_reply cp;
+		if (test_bit(HCI_SC_ENABLED, &hdev->dev_flags)) {
+			struct hci_cp_remote_oob_ext_data_reply cp;
 
-		bacpy(&cp.bdaddr, &ev->bdaddr);
-		memcpy(cp.hash, data->hash, sizeof(cp.hash));
-		memcpy(cp.randomizer, data->randomizer, sizeof(cp.randomizer));
+			bacpy(&cp.bdaddr, &ev->bdaddr);
+			memcpy(cp.hash192, data->hash192, sizeof(cp.hash192));
+			memcpy(cp.randomizer192, data->randomizer192,
+			       sizeof(cp.randomizer192));
+			memcpy(cp.hash256, data->hash256, sizeof(cp.hash256));
+			memcpy(cp.randomizer256, data->randomizer256,
+			       sizeof(cp.randomizer256));
+
+			hci_send_cmd(hdev, HCI_OP_REMOTE_OOB_EXT_DATA_REPLY,
+				     sizeof(cp), &cp);
+		} else {
+			struct hci_cp_remote_oob_data_reply cp;
 
-		hci_send_cmd(hdev, HCI_OP_REMOTE_OOB_DATA_REPLY, sizeof(cp),
-			     &cp);
+			bacpy(&cp.bdaddr, &ev->bdaddr);
+			memcpy(cp.hash, data->hash192, sizeof(cp.hash));
+			memcpy(cp.randomizer, data->randomizer192,
+			       sizeof(cp.randomizer));
+
+			hci_send_cmd(hdev, HCI_OP_REMOTE_OOB_DATA_REPLY,
+				     sizeof(cp), &cp);
+		}
 	} else {
 		struct hci_cp_remote_oob_data_neg_reply cp;
 
 		bacpy(&cp.bdaddr, &ev->bdaddr);
-		hci_send_cmd(hdev, HCI_OP_REMOTE_OOB_DATA_NEG_REPLY, sizeof(cp),
-			     &cp);
+		hci_send_cmd(hdev, HCI_OP_REMOTE_OOB_DATA_NEG_REPLY,
+			     sizeof(cp), &cp);
 	}
 
 unlock:
-- 
1.8.4.2


^ permalink raw reply related

* [PATCH v4 12/15] Bluetooth: Add debugfs quirk for forcing Secure Connections support
From: Marcel Holtmann @ 2014-01-10 10:07 UTC (permalink / raw)
  To: linux-bluetooth

The Bluetooth 4.1 specification with Secure Connections support has
just been released and controllers with this feature are still in
an early stage.

A handful of controllers have already support for it, but they do
not always identify this feature correctly. This debugfs entry
allows to tell the kernel that the controller can be treated as
it would fully support Secure Connections.

Using debugfs to force Secure Connections support of course does
not make this feature magically appear in all controllers. This
is a debug functionality for early adopters. Once the majority
of controllers matures this quirk will be removed.

Signed-off-by: Marcel Holtmann <marcel@holtmann.org>
---
 include/net/bluetooth/hci.h |  1 +
 net/bluetooth/hci_core.c    | 51 ++++++++++++++++++++++++++++++++++++++++++++-
 net/bluetooth/mgmt.c        |  6 ++++--
 3 files changed, 55 insertions(+), 3 deletions(-)

diff --git a/include/net/bluetooth/hci.h b/include/net/bluetooth/hci.h
index 0253276e88e4..2bc19881e250 100644
--- a/include/net/bluetooth/hci.h
+++ b/include/net/bluetooth/hci.h
@@ -117,6 +117,7 @@ enum {
 	HCI_SERVICE_CACHE,
 	HCI_DEBUG_KEYS,
 	HCI_DUT_MODE,
+	HCI_FORCE_SC,
 	HCI_UNREGISTER,
 	HCI_USER_CHANNEL,
 
diff --git a/net/bluetooth/hci_core.c b/net/bluetooth/hci_core.c
index b3b619a448b5..946631ffe802 100644
--- a/net/bluetooth/hci_core.c
+++ b/net/bluetooth/hci_core.c
@@ -415,6 +415,52 @@ static int ssp_debug_mode_get(void *data, u64 *val)
 DEFINE_SIMPLE_ATTRIBUTE(ssp_debug_mode_fops, ssp_debug_mode_get,
 			ssp_debug_mode_set, "%llu\n");
 
+static ssize_t force_sc_support_read(struct file *file, char __user *user_buf,
+				     size_t count, loff_t *ppos)
+{
+	struct hci_dev *hdev = file->private_data;
+	char buf[3];
+
+	buf[0] = test_bit(HCI_FORCE_SC, &hdev->dev_flags) ? 'Y': 'N';
+	buf[1] = '\n';
+	buf[2] = '\0';
+	return simple_read_from_buffer(user_buf, count, ppos, buf, 2);
+}
+
+static ssize_t force_sc_support_write(struct file *file,
+				      const char __user *user_buf,
+				      size_t count, loff_t *ppos)
+{
+	struct hci_dev *hdev = file->private_data;
+	char buf[32];
+	size_t buf_size = min(count, (sizeof(buf)-1));
+	bool enable;
+
+	if (test_bit(HCI_UP, &hdev->flags))
+		return -EBUSY;
+
+	if (copy_from_user(buf, user_buf, buf_size))
+		return -EFAULT;
+
+	buf[buf_size] = '\0';
+	if (strtobool(buf, &enable))
+		return -EINVAL;
+
+	if (enable == test_bit(HCI_FORCE_SC, &hdev->dev_flags))
+		return -EALREADY;
+
+	change_bit(HCI_FORCE_SC, &hdev->dev_flags);
+
+	return count;
+}
+
+static const struct file_operations force_sc_support_fops = {
+	.open		= simple_open,
+	.read		= force_sc_support_read,
+	.write		= force_sc_support_write,
+	.llseek		= default_llseek,
+};
+
 static int idle_timeout_set(void *data, u64 val)
 {
 	struct hci_dev *hdev = data;
@@ -1365,7 +1411,8 @@ static void hci_init4_req(struct hci_request *req, unsigned long opt)
 		hci_req_add(req, HCI_OP_READ_SYNC_TRAIN_PARAMS, 0, NULL);
 
 	/* Enable Secure Connections if supported and configured */
-	if (lmp_sc_capable(hdev) &&
+	if ((lmp_sc_capable(hdev) ||
+	     test_bit(HCI_FORCE_SC, &hdev->dev_flags)) &&
 	    test_bit(HCI_SC_ENABLED, &hdev->dev_flags)) {
 		u8 support = 0x01;
 		hci_req_add(req, HCI_OP_WRITE_SC_SUPPORT,
@@ -1442,6 +1489,8 @@ static int __hci_init(struct hci_dev *hdev)
 				    hdev, &auto_accept_delay_fops);
 		debugfs_create_file("ssp_debug_mode", 0644, hdev->debugfs,
 				    hdev, &ssp_debug_mode_fops);
+		debugfs_create_file("force_sc_support", 0644, hdev->debugfs,
+				    hdev, &force_sc_support_fops);
 	}
 
 	if (lmp_sniff_capable(hdev)) {
diff --git a/net/bluetooth/mgmt.c b/net/bluetooth/mgmt.c
index a7d4ae679ab7..bbe30c983492 100644
--- a/net/bluetooth/mgmt.c
+++ b/net/bluetooth/mgmt.c
@@ -378,7 +378,8 @@ static u32 get_supported_settings(struct hci_dev *hdev)
 			settings |= MGMT_SETTING_HS;
 		}
 
-		if (lmp_sc_capable(hdev))
+		if (lmp_sc_capable(hdev) ||
+		    test_bit(HCI_FORCE_SC, &hdev->dev_flags))
 			settings |= MGMT_SETTING_SECURE_CONN;
 	}
 
@@ -4026,7 +4027,8 @@ static int set_secure_conn(struct sock *sk, struct hci_dev *hdev,
 		return cmd_status(sk, hdev->id, MGMT_OP_SET_SECURE_CONN,
 				  status);
 
-	if (!lmp_sc_capable(hdev))
+	if (!lmp_sc_capable(hdev) &&
+	    !test_bit(HCI_FORCE_SC, &hdev->dev_flags))
 		return cmd_status(sk, hdev->id, MGMT_OP_SET_SECURE_CONN,
 				  MGMT_STATUS_NOT_SUPPORTED);
 
-- 
1.8.4.2


^ permalink raw reply related

* [PATCH v4 11/15] Bluetooth: Add support for local OOB data with Secure Connections
From: Marcel Holtmann @ 2014-01-10 10:07 UTC (permalink / raw)
  To: linux-bluetooth

For Secure Connections support and the usage of out-of-band pairing,
it is needed to read the P-256 hash and randomizer or P-192 hash and
randomizer. This change will read P-192 data when Secure Connections
is disabled and P-192 and P-256 data when it is enabled.

The difference is between using HCI Read Local OOB Data and using the
new HCI Read Local OOB Extended Data command. The first one has been
introduced with Bluetooth 2.1 and returns only the P-192 data.

< HCI Command: Read Local OOB Data (0x03|0x0057) plen 0
> HCI Event: Command Complete (0x0e) plen 36
      Read Local OOB Data (0x03|0x0057) ncmd 1
        Status: Success (0x00)
        Hash C from P-192: 975a59baa1c4eee391477cb410b23e6d
        Randomizer R with P-192: 9ee63b7dec411d3b467c5ae446df7f7d

The second command has been introduced with Bluetooth 4.1 and will
return P-192 and P-256 data.

< HCI Command: Read Local OOB Extended Data (0x03|0x007d) plen 0
> HCI Event: Command Complete (0x0e) plen 68
      Read Local OOB Extended Data (0x03|0x007d) ncmd 1
        Status: Success (0x00)
        Hash C from P-192: 6489731804b156fa6355efb8124a1389
        Randomizer R with P-192: 4781d5352fb215b2958222b3937b6026
        Hash C from P-256: 69ef8a928b9d07fc149e630e74ecb991
        Randomizer R with P-256: 4781d5352fb215b2958222b3937b6026

The change for the management interface is transparent and no change
is required for existing userspace. The Secure Connections feature
needs to be manually enabled. When it is disabled, then userspace
only gets the P-192 returned and with Secure Connections enabled,
userspace gets P-192 and P-256 in an extended structure.

It is also acceptable to just ignore the P-256 data since it is not
required to support them. The pairing with out-of-band credentials
will still succeed. However then of course no Secure Connection will
b established.

Signed-off-by: Marcel Holtmann <marcel@holtmann.org>
---
 include/net/bluetooth/hci_core.h |  5 +++--
 include/net/bluetooth/mgmt.h     |  6 ++++++
 net/bluetooth/hci_event.c        | 28 ++++++++++++++++++++++-----
 net/bluetooth/mgmt.c             | 41 ++++++++++++++++++++++++++++++++--------
 4 files changed, 65 insertions(+), 15 deletions(-)

diff --git a/include/net/bluetooth/hci_core.h b/include/net/bluetooth/hci_core.h
index 1eb55ec40ac0..bd15eaa4c06e 100644
--- a/include/net/bluetooth/hci_core.h
+++ b/include/net/bluetooth/hci_core.h
@@ -1129,8 +1129,9 @@ void mgmt_sc_enable_complete(struct hci_dev *hdev, u8 enable, u8 status);
 void mgmt_set_class_of_dev_complete(struct hci_dev *hdev, u8 *dev_class,
 				    u8 status);
 void mgmt_set_local_name_complete(struct hci_dev *hdev, u8 *name, u8 status);
-void mgmt_read_local_oob_data_reply_complete(struct hci_dev *hdev, u8 *hash,
-					     u8 *randomizer, u8 status);
+void mgmt_read_local_oob_data_complete(struct hci_dev *hdev, u8 *hash192,
+				       u8 *randomizer192, u8 *hash256,
+				       u8 *randomizer256, u8 status);
 void mgmt_device_found(struct hci_dev *hdev, bdaddr_t *bdaddr, u8 link_type,
 		       u8 addr_type, u8 *dev_class, s8 rssi, u8 cfm_name,
 		       u8 ssp, u8 *eir, u16 eir_len);
diff --git a/include/net/bluetooth/mgmt.h b/include/net/bluetooth/mgmt.h
index 8a2c78175997..036ddc7dc7ed 100644
--- a/include/net/bluetooth/mgmt.h
+++ b/include/net/bluetooth/mgmt.h
@@ -295,6 +295,12 @@ struct mgmt_rp_read_local_oob_data {
 	__u8	hash[16];
 	__u8	randomizer[16];
 } __packed;
+struct mgmt_rp_read_local_oob_ext_data {
+	__u8	hash192[16];
+	__u8	randomizer192[16];
+	__u8	hash256[16];
+	__u8	randomizer256[16];
+} __packed;
 
 #define MGMT_OP_ADD_REMOTE_OOB_DATA	0x0021
 struct mgmt_cp_add_remote_oob_data {
diff --git a/net/bluetooth/hci_event.c b/net/bluetooth/hci_event.c
index 820a01965ce3..6923241d2b3e 100644
--- a/net/bluetooth/hci_event.c
+++ b/net/bluetooth/hci_event.c
@@ -932,16 +932,30 @@ static void hci_cc_user_passkey_neg_reply(struct hci_dev *hdev,
 	hci_dev_unlock(hdev);
 }
 
-static void hci_cc_read_local_oob_data_reply(struct hci_dev *hdev,
-					     struct sk_buff *skb)
+static void hci_cc_read_local_oob_data(struct hci_dev *hdev,
+				       struct sk_buff *skb)
 {
 	struct hci_rp_read_local_oob_data *rp = (void *) skb->data;
 
 	BT_DBG("%s status 0x%2.2x", hdev->name, rp->status);
 
 	hci_dev_lock(hdev);
-	mgmt_read_local_oob_data_reply_complete(hdev, rp->hash,
-						rp->randomizer, rp->status);
+	mgmt_read_local_oob_data_complete(hdev, rp->hash, rp->randomizer,
+					  NULL, NULL, rp->status);
+	hci_dev_unlock(hdev);
+}
+
+static void hci_cc_read_local_oob_ext_data(struct hci_dev *hdev,
+					   struct sk_buff *skb)
+{
+	struct hci_rp_read_local_oob_ext_data *rp = (void *) skb->data;
+
+	BT_DBG("%s status 0x%2.2x", hdev->name, rp->status);
+
+	hci_dev_lock(hdev);
+	mgmt_read_local_oob_data_complete(hdev, rp->hash192, rp->randomizer192,
+					  rp->hash256, rp->randomizer256,
+					  rp->status);
 	hci_dev_unlock(hdev);
 }
 
@@ -2248,7 +2262,11 @@ static void hci_cmd_complete_evt(struct hci_dev *hdev, struct sk_buff *skb)
 		break;
 
 	case HCI_OP_READ_LOCAL_OOB_DATA:
-		hci_cc_read_local_oob_data_reply(hdev, skb);
+		hci_cc_read_local_oob_data(hdev, skb);
+		break;
+
+	case HCI_OP_READ_LOCAL_OOB_EXT_DATA:
+		hci_cc_read_local_oob_ext_data(hdev, skb);
 		break;
 
 	case HCI_OP_LE_READ_BUFFER_SIZE:
diff --git a/net/bluetooth/mgmt.c b/net/bluetooth/mgmt.c
index 9b162038acb7..a7d4ae679ab7 100644
--- a/net/bluetooth/mgmt.c
+++ b/net/bluetooth/mgmt.c
@@ -3078,7 +3078,12 @@ static int read_local_oob_data(struct sock *sk, struct hci_dev *hdev,
 		goto unlock;
 	}
 
-	err = hci_send_cmd(hdev, HCI_OP_READ_LOCAL_OOB_DATA, 0, NULL);
+	if (test_bit(HCI_SC_ENABLED, &hdev->dev_flags))
+		err = hci_send_cmd(hdev, HCI_OP_READ_LOCAL_OOB_EXT_DATA,
+				   0, NULL);
+	else
+		err = hci_send_cmd(hdev, HCI_OP_READ_LOCAL_OOB_DATA, 0, NULL);
+
 	if (err < 0)
 		mgmt_pending_remove(cmd);
 
@@ -5077,8 +5082,9 @@ void mgmt_set_local_name_complete(struct hci_dev *hdev, u8 *name, u8 status)
 		   cmd ? cmd->sk : NULL);
 }
 
-void mgmt_read_local_oob_data_reply_complete(struct hci_dev *hdev, u8 *hash,
-					     u8 *randomizer, u8 status)
+void mgmt_read_local_oob_data_complete(struct hci_dev *hdev, u8 *hash192,
+				       u8 *randomizer192, u8 *hash256,
+				       u8 *randomizer256, u8 status)
 {
 	struct pending_cmd *cmd;
 
@@ -5092,13 +5098,32 @@ void mgmt_read_local_oob_data_reply_complete(struct hci_dev *hdev, u8 *hash,
 		cmd_status(cmd->sk, hdev->id, MGMT_OP_READ_LOCAL_OOB_DATA,
 			   mgmt_status(status));
 	} else {
-		struct mgmt_rp_read_local_oob_data rp;
+		if (test_bit(HCI_SC_ENABLED, &hdev->dev_flags) &&
+		    hash256 && randomizer256) {
+			struct mgmt_rp_read_local_oob_ext_data rp;
+
+			memcpy(rp.hash192, hash192, sizeof(rp.hash192));
+			memcpy(rp.randomizer192, randomizer192,
+			       sizeof(rp.randomizer192));
 
-		memcpy(rp.hash, hash, sizeof(rp.hash));
-		memcpy(rp.randomizer, randomizer, sizeof(rp.randomizer));
+			memcpy(rp.hash256, hash256, sizeof(rp.hash256));
+			memcpy(rp.randomizer256, randomizer256,
+			       sizeof(rp.randomizer256));
 
-		cmd_complete(cmd->sk, hdev->id, MGMT_OP_READ_LOCAL_OOB_DATA,
-			     0, &rp, sizeof(rp));
+			cmd_complete(cmd->sk, hdev->id,
+				     MGMT_OP_READ_LOCAL_OOB_DATA, 0,
+				     &rp, sizeof(rp));
+		} else {
+			struct mgmt_rp_read_local_oob_data rp;
+
+			memcpy(rp.hash, hash192, sizeof(rp.hash));
+			memcpy(rp.randomizer, randomizer192,
+			       sizeof(rp.randomizer));
+
+			cmd_complete(cmd->sk, hdev->id,
+				     MGMT_OP_READ_LOCAL_OOB_DATA, 0,
+				     &rp, sizeof(rp));
+		}
 	}
 
 	mgmt_pending_remove(cmd);
-- 
1.8.4.2


^ permalink raw reply related

* [PATCH v4 10/15] Bluetooth: Limit acceptable link key types to only supported ones
From: Marcel Holtmann @ 2014-01-10 10:07 UTC (permalink / raw)
  To: linux-bluetooth

The link keys that are loaded by userspace during controller setup
should be limited to actual valid and supported types. With the
support for Secure Connections, it is limited to types 0x00 - 0x08
at the moment. Reject any other link key types.

Signed-off-by: Marcel Holtmann <marcel@holtmann.org>
---
 net/bluetooth/mgmt.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/net/bluetooth/mgmt.c b/net/bluetooth/mgmt.c
index 68a3c998d19c..9b162038acb7 100644
--- a/net/bluetooth/mgmt.c
+++ b/net/bluetooth/mgmt.c
@@ -2241,7 +2241,7 @@ static int load_link_keys(struct sock *sk, struct hci_dev *hdev, void *data,
 	for (i = 0; i < key_count; i++) {
 		struct mgmt_link_key_info *key = &cp->keys[i];
 
-		if (key->addr.type != BDADDR_BREDR)
+		if (key->addr.type != BDADDR_BREDR || key->type > 0x08)
 			return cmd_status(sk, hdev->id, MGMT_OP_LOAD_LINK_KEYS,
 					  MGMT_STATUS_INVALID_PARAMS);
 	}
-- 
1.8.4.2


^ permalink raw reply related

* [PATCH v4 09/15] Bluetooth: Enable Secure Connection during power on if configured
From: Marcel Holtmann @ 2014-01-10 10:07 UTC (permalink / raw)
  To: linux-bluetooth

If support for Secure Connection has been configured, then make sure
to send the appropiate HCI command to enable it when powering on the
controller.

Signed-off-by: Marcel Holtmann <marcel@holtmann.org>
---
 net/bluetooth/hci_core.c | 8 ++++++++
 1 file changed, 8 insertions(+)

diff --git a/net/bluetooth/hci_core.c b/net/bluetooth/hci_core.c
index 52e398f37129..b3b619a448b5 100644
--- a/net/bluetooth/hci_core.c
+++ b/net/bluetooth/hci_core.c
@@ -1363,6 +1363,14 @@ static void hci_init4_req(struct hci_request *req, unsigned long opt)
 	/* Check for Synchronization Train support */
 	if (lmp_sync_train_capable(hdev))
 		hci_req_add(req, HCI_OP_READ_SYNC_TRAIN_PARAMS, 0, NULL);
+
+	/* Enable Secure Connections if supported and configured */
+	if (lmp_sc_capable(hdev) &&
+	    test_bit(HCI_SC_ENABLED, &hdev->dev_flags)) {
+		u8 support = 0x01;
+		hci_req_add(req, HCI_OP_WRITE_SC_SUPPORT,
+			    sizeof(support), &support);
+	}
 }
 
 static int __hci_init(struct hci_dev *hdev)
-- 
1.8.4.2


^ permalink raw reply related

* [PATCH v4 08/15] Bluetooth: Add management command for enabling Secure Connections
From: Marcel Holtmann @ 2014-01-10 10:07 UTC (permalink / raw)
  To: linux-bluetooth

The support for Secure Connections need to be explicitly enabled by
userspace. This is required since only userspace that can handle the
new link key types should enable support for Secure Connections.

This command handling is similar to how Secure Simple Pairing enabling
is done. It also tracks the case when Secure Connections support is
enabled via raw HCI commands. This makes sure that the host features
page is updated as well.

Signed-off-by: Marcel Holtmann <marcel@holtmann.org>
---
 include/net/bluetooth/hci_core.h |   1 +
 include/net/bluetooth/mgmt.h     |   2 +
 net/bluetooth/hci_event.c        |  32 ++++++++++++
 net/bluetooth/mgmt.c             | 106 +++++++++++++++++++++++++++++++++++++++
 4 files changed, 141 insertions(+)

diff --git a/include/net/bluetooth/hci_core.h b/include/net/bluetooth/hci_core.h
index bb984d0626b7..1eb55ec40ac0 100644
--- a/include/net/bluetooth/hci_core.h
+++ b/include/net/bluetooth/hci_core.h
@@ -1125,6 +1125,7 @@ void mgmt_auth_failed(struct hci_dev *hdev, bdaddr_t *bdaddr, u8 link_type,
 		      u8 addr_type, u8 status);
 void mgmt_auth_enable_complete(struct hci_dev *hdev, u8 status);
 void mgmt_ssp_enable_complete(struct hci_dev *hdev, u8 enable, u8 status);
+void mgmt_sc_enable_complete(struct hci_dev *hdev, u8 enable, u8 status);
 void mgmt_set_class_of_dev_complete(struct hci_dev *hdev, u8 *dev_class,
 				    u8 status);
 void mgmt_set_local_name_complete(struct hci_dev *hdev, u8 *name, u8 status);
diff --git a/include/net/bluetooth/mgmt.h b/include/net/bluetooth/mgmt.h
index 4ec17dec62e0..8a2c78175997 100644
--- a/include/net/bluetooth/mgmt.h
+++ b/include/net/bluetooth/mgmt.h
@@ -370,6 +370,8 @@ struct mgmt_cp_set_scan_params {
 } __packed;
 #define MGMT_SET_SCAN_PARAMS_SIZE	4
 
+#define MGMT_OP_SET_SECURE_CONN		0x002D
+
 #define MGMT_EV_CMD_COMPLETE		0x0001
 struct mgmt_ev_cmd_complete {
 	__le16	opcode;
diff --git a/net/bluetooth/hci_event.c b/net/bluetooth/hci_event.c
index b3c5396e0c1b..820a01965ce3 100644
--- a/net/bluetooth/hci_event.c
+++ b/net/bluetooth/hci_event.c
@@ -461,6 +461,34 @@ static void hci_cc_write_ssp_mode(struct hci_dev *hdev, struct sk_buff *skb)
 	}
 }
 
+static void hci_cc_write_sc_support(struct hci_dev *hdev, struct sk_buff *skb)
+{
+	__u8 status = *((__u8 *) skb->data);
+	struct hci_cp_write_sc_support *sent;
+
+	BT_DBG("%s status 0x%2.2x", hdev->name, status);
+
+	sent = hci_sent_cmd_data(hdev, HCI_OP_WRITE_SC_SUPPORT);
+	if (!sent)
+		return;
+
+	if (!status) {
+		if (sent->support)
+			hdev->features[1][0] |= LMP_HOST_SC;
+		else
+			hdev->features[1][0] &= ~LMP_HOST_SC;
+	}
+
+	if (test_bit(HCI_MGMT, &hdev->dev_flags))
+		mgmt_sc_enable_complete(hdev, sent->support, status);
+	else if (!status) {
+		if (sent->support)
+			set_bit(HCI_SC_ENABLED, &hdev->dev_flags);
+		else
+			clear_bit(HCI_SC_ENABLED, &hdev->dev_flags);
+	}
+}
+
 static void hci_cc_read_local_version(struct hci_dev *hdev, struct sk_buff *skb)
 {
 	struct hci_rp_read_local_version *rp = (void *) skb->data;
@@ -2147,6 +2175,10 @@ static void hci_cmd_complete_evt(struct hci_dev *hdev, struct sk_buff *skb)
 		hci_cc_write_ssp_mode(hdev, skb);
 		break;
 
+	case HCI_OP_WRITE_SC_SUPPORT:
+		hci_cc_write_sc_support(hdev, skb);
+		break;
+
 	case HCI_OP_READ_LOCAL_VERSION:
 		hci_cc_read_local_version(hdev, skb);
 		break;
diff --git a/net/bluetooth/mgmt.c b/net/bluetooth/mgmt.c
index b00fa0253cba..68a3c998d19c 100644
--- a/net/bluetooth/mgmt.c
+++ b/net/bluetooth/mgmt.c
@@ -4006,6 +4006,79 @@ unlock:
 	return err;
 }
 
+static int set_secure_conn(struct sock *sk, struct hci_dev *hdev,
+			   void *data, u16 len)
+{
+	struct mgmt_mode *cp = data;
+	struct pending_cmd *cmd;
+	u8 status;
+	int err;
+
+	BT_DBG("request for %s", hdev->name);
+
+	status = mgmt_bredr_support(hdev);
+	if (status)
+		return cmd_status(sk, hdev->id, MGMT_OP_SET_SECURE_CONN,
+				  status);
+
+	if (!lmp_sc_capable(hdev))
+		return cmd_status(sk, hdev->id, MGMT_OP_SET_SECURE_CONN,
+				  MGMT_STATUS_NOT_SUPPORTED);
+
+	if (cp->val != 0x00 && cp->val != 0x01)
+		return cmd_status(sk, hdev->id, MGMT_OP_SET_SECURE_CONN,
+				  MGMT_STATUS_INVALID_PARAMS);
+
+	hci_dev_lock(hdev);
+
+	if (!hdev_is_powered(hdev)) {
+		bool changed;
+
+		if (cp->val)
+			changed = !test_and_set_bit(HCI_SC_ENABLED,
+						    &hdev->dev_flags);
+		else
+			changed = test_and_clear_bit(HCI_SC_ENABLED,
+						     &hdev->dev_flags);
+
+		err = send_settings_rsp(sk, MGMT_OP_SET_SECURE_CONN, hdev);
+		if (err < 0)
+			goto failed;
+
+		if (changed)
+			err = new_settings(hdev, sk);
+
+		goto failed;
+	}
+
+	if (mgmt_pending_find(MGMT_OP_SET_SECURE_CONN, hdev)) {
+		err = cmd_status(sk, hdev->id, MGMT_OP_SET_SECURE_CONN,
+				 MGMT_STATUS_BUSY);
+		goto failed;
+	}
+
+	if (!!cp->val == test_bit(HCI_SC_ENABLED, &hdev->dev_flags)) {
+		err = send_settings_rsp(sk, MGMT_OP_SET_SECURE_CONN, hdev);
+		goto failed;
+	}
+
+	cmd = mgmt_pending_add(sk, MGMT_OP_SET_SECURE_CONN, hdev, data, len);
+	if (!cmd) {
+		err = -ENOMEM;
+		goto failed;
+	}
+
+	err = hci_send_cmd(hdev, HCI_OP_WRITE_SC_SUPPORT, 1, &cp->val);
+	if (err < 0) {
+		mgmt_pending_remove(cmd);
+		goto failed;
+	}
+
+failed:
+	hci_dev_unlock(hdev);
+	return err;
+}
+
 static bool ltk_is_valid(struct mgmt_ltk_info *key)
 {
 	if (key->authenticated != 0x00 && key->authenticated != 0x01)
@@ -4134,6 +4207,7 @@ static const struct mgmt_handler {
 	{ set_bredr,              false, MGMT_SETTING_SIZE },
 	{ set_static_address,     false, MGMT_SET_STATIC_ADDRESS_SIZE },
 	{ set_scan_params,        false, MGMT_SET_SCAN_PARAMS_SIZE },
+	{ set_secure_conn,        false, MGMT_SETTING_SIZE },
 };
 
 
@@ -4917,6 +4991,38 @@ void mgmt_ssp_enable_complete(struct hci_dev *hdev, u8 enable, u8 status)
 	hci_req_run(&req, NULL);
 }
 
+void mgmt_sc_enable_complete(struct hci_dev *hdev, u8 enable, u8 status)
+{
+	struct cmd_lookup match = { NULL, hdev };
+	bool changed = false;
+
+	if (status) {
+		u8 mgmt_err = mgmt_status(status);
+
+		if (enable && test_and_clear_bit(HCI_SC_ENABLED,
+						 &hdev->dev_flags))
+			new_settings(hdev, NULL);
+
+		mgmt_pending_foreach(MGMT_OP_SET_SECURE_CONN, hdev,
+				     cmd_status_rsp, &mgmt_err);
+		return;
+	}
+
+	if (enable)
+		changed = !test_and_set_bit(HCI_SC_ENABLED, &hdev->dev_flags);
+	else
+		changed = test_and_clear_bit(HCI_SC_ENABLED, &hdev->dev_flags);
+
+	mgmt_pending_foreach(MGMT_OP_SET_SECURE_CONN, hdev,
+			     settings_rsp, &match);
+
+	if (changed)
+		new_settings(hdev, match.sk);
+
+	if (match.sk)
+		sock_put(match.sk);
+}
+
 static void sk_lookup(struct pending_cmd *cmd, void *data)
 {
 	struct cmd_lookup *match = data;
-- 
1.8.4.2


^ permalink raw reply related

* [PATCH v4 07/15] Bluetooth: Add flags and setting for Secure Connections support
From: Marcel Holtmann @ 2014-01-10 10:07 UTC (permalink / raw)
  To: linux-bluetooth

The MGMT_SETTING_SECURE_CONN setting is used to track the support and
status for Secure Connections from the management interface. For HCI
based tracking HCI_SC_ENABLED flag is used.

Signed-off-by: Marcel Holtmann <marcel@holtmann.org>
---
 include/net/bluetooth/hci.h  | 1 +
 include/net/bluetooth/mgmt.h | 1 +
 net/bluetooth/mgmt.c         | 7 +++++++
 3 files changed, 9 insertions(+)

diff --git a/include/net/bluetooth/hci.h b/include/net/bluetooth/hci.h
index 8d888bc432c6..0253276e88e4 100644
--- a/include/net/bluetooth/hci.h
+++ b/include/net/bluetooth/hci.h
@@ -122,6 +122,7 @@ enum {
 
 	HCI_LE_SCAN,
 	HCI_SSP_ENABLED,
+	HCI_SC_ENABLED,
 	HCI_HS_ENABLED,
 	HCI_LE_ENABLED,
 	HCI_ADVERTISING,
diff --git a/include/net/bluetooth/mgmt.h b/include/net/bluetooth/mgmt.h
index 518c5c84e39a..4ec17dec62e0 100644
--- a/include/net/bluetooth/mgmt.h
+++ b/include/net/bluetooth/mgmt.h
@@ -94,6 +94,7 @@ struct mgmt_rp_read_index_list {
 #define MGMT_SETTING_HS			0x00000100
 #define MGMT_SETTING_LE			0x00000200
 #define MGMT_SETTING_ADVERTISING	0x00000400
+#define MGMT_SETTING_SECURE_CONN	0x00000800
 
 #define MGMT_OP_READ_INFO		0x0004
 #define MGMT_READ_INFO_SIZE		0
diff --git a/net/bluetooth/mgmt.c b/net/bluetooth/mgmt.c
index a03ca3ca91bf..b00fa0253cba 100644
--- a/net/bluetooth/mgmt.c
+++ b/net/bluetooth/mgmt.c
@@ -79,6 +79,7 @@ static const u16 mgmt_commands[] = {
 	MGMT_OP_SET_BREDR,
 	MGMT_OP_SET_STATIC_ADDRESS,
 	MGMT_OP_SET_SCAN_PARAMS,
+	MGMT_OP_SET_SECURE_CONN,
 };
 
 static const u16 mgmt_events[] = {
@@ -376,6 +377,9 @@ static u32 get_supported_settings(struct hci_dev *hdev)
 			settings |= MGMT_SETTING_SSP;
 			settings |= MGMT_SETTING_HS;
 		}
+
+		if (lmp_sc_capable(hdev))
+			settings |= MGMT_SETTING_SECURE_CONN;
 	}
 
 	if (lmp_le_capable(hdev)) {
@@ -423,6 +427,9 @@ static u32 get_current_settings(struct hci_dev *hdev)
 	if (test_bit(HCI_ADVERTISING, &hdev->dev_flags))
 		settings |= MGMT_SETTING_ADVERTISING;
 
+	if (test_bit(HCI_SC_ENABLED, &hdev->dev_flags))
+		settings |= MGMT_SETTING_SECURE_CONN;
+
 	return settings;
 }
 
-- 
1.8.4.2


^ permalink raw reply related

* [PATCH v4 06/15] Bluetooth: Enable Authenticated Payload Timeout Expired event
From: Marcel Holtmann @ 2014-01-10 10:07 UTC (permalink / raw)
  To: linux-bluetooth

With Secure Connections capable controllers, the authenticated payload
timeout can trigger. Enable the event so the controller informs the
host when this happens.

Signed-off-by: Marcel Holtmann <marcel@holtmann.org>
---
 net/bluetooth/hci_core.c | 4 ++++
 1 file changed, 4 insertions(+)

diff --git a/net/bluetooth/hci_core.c b/net/bluetooth/hci_core.c
index 5e8663c194c1..52e398f37129 100644
--- a/net/bluetooth/hci_core.c
+++ b/net/bluetooth/hci_core.c
@@ -1288,6 +1288,10 @@ static void hci_set_event_mask_page_2(struct hci_request *req)
 		events[2] |= 0x08;	/* Truncated Page Complete */
 	}
 
+	/* Enable Authenticated Payload Timeout Expired event if supported */
+	if (lmp_ping_capable(hdev))
+		events[2] |= 0x80;
+
 	hci_req_add(req, HCI_OP_SET_EVENT_MASK_PAGE_2, sizeof(events), events);
 }
 
-- 
1.8.4.2


^ permalink raw reply related

* [PATCH v4 05/15] Bluetooth: Add support for handling P-256 derived link keys
From: Marcel Holtmann @ 2014-01-10 10:07 UTC (permalink / raw)
  To: linux-bluetooth

Before being able to enable Secure Connections support, the core needs
to know on how to handle P-256 derived link keys. The difference between
authenticated and unauthenticated P-256 derived link keys is the same as
its P-192 counter parts.

Signed-off-by: Marcel Holtmann <marcel@holtmann.org>
---
 net/bluetooth/hci_conn.c  | 6 ++++--
 net/bluetooth/hci_event.c | 3 ++-
 2 files changed, 6 insertions(+), 3 deletions(-)

diff --git a/net/bluetooth/hci_conn.c b/net/bluetooth/hci_conn.c
index 251f22e32fbf..cf96b3438a91 100644
--- a/net/bluetooth/hci_conn.c
+++ b/net/bluetooth/hci_conn.c
@@ -802,12 +802,14 @@ int hci_conn_security(struct hci_conn *conn, __u8 sec_level, __u8 auth_type)
 
 	/* An authenticated combination key has sufficient security for any
 	   security level. */
-	if (conn->key_type == HCI_LK_AUTH_COMBINATION_P192)
+	if (conn->key_type == HCI_LK_AUTH_COMBINATION_P192 ||
+	    conn->key_type == HCI_LK_AUTH_COMBINATION_P256)
 		goto encrypt;
 
 	/* An unauthenticated combination key has sufficient security for
 	   security level 1 and 2. */
-	if (conn->key_type == HCI_LK_UNAUTH_COMBINATION_P192 &&
+	if ((conn->key_type == HCI_LK_UNAUTH_COMBINATION_P192 ||
+	     conn->key_type == HCI_LK_UNAUTH_COMBINATION_P256) &&
 	    (sec_level == BT_SECURITY_MEDIUM || sec_level == BT_SECURITY_LOW))
 		goto encrypt;
 
diff --git a/net/bluetooth/hci_event.c b/net/bluetooth/hci_event.c
index defa1252b534..b3c5396e0c1b 100644
--- a/net/bluetooth/hci_event.c
+++ b/net/bluetooth/hci_event.c
@@ -2633,7 +2633,8 @@ static void hci_link_key_request_evt(struct hci_dev *hdev, struct sk_buff *skb)
 
 	conn = hci_conn_hash_lookup_ba(hdev, ACL_LINK, &ev->bdaddr);
 	if (conn) {
-		if (key->type == HCI_LK_UNAUTH_COMBINATION_P192 &&
+		if ((key->type == HCI_LK_UNAUTH_COMBINATION_P192 ||
+		     key->type == HCI_LK_UNAUTH_COMBINATION_P256) &&
 		    conn->auth_type != 0xff && (conn->auth_type & 0x01)) {
 			BT_DBG("%s ignoring unauthenticated key", hdev->name);
 			goto not_found;
-- 
1.8.4.2


^ permalink raw reply related

* [PATCH v4 04/15] Bluetooth: Add definitions for new link key types
From: Marcel Holtmann @ 2014-01-10 10:07 UTC (permalink / raw)
  To: linux-bluetooth

With the introduction of Secure Connections, the list of link key types
got extended by P-256 versions of authenticated and unauthenticated
link keys.

To avoid any confusion the previous authenticated and unauthenticated
link key types got ammended with a P912 postfix. And the two new keys
have a P256 postfix now. Existing code using the previous definitions
has been adjusted.

Signed-off-by: Marcel Holtmann <marcel@holtmann.org>
---
 include/net/bluetooth/hci.h | 6 ++++--
 net/bluetooth/hci_conn.c    | 4 ++--
 net/bluetooth/hci_event.c   | 2 +-
 3 files changed, 7 insertions(+), 5 deletions(-)

diff --git a/include/net/bluetooth/hci.h b/include/net/bluetooth/hci.h
index e4e94bfc5232..8d888bc432c6 100644
--- a/include/net/bluetooth/hci.h
+++ b/include/net/bluetooth/hci.h
@@ -331,9 +331,11 @@ enum {
 #define HCI_LK_LOCAL_UNIT		0x01
 #define HCI_LK_REMOTE_UNIT		0x02
 #define HCI_LK_DEBUG_COMBINATION	0x03
-#define HCI_LK_UNAUTH_COMBINATION	0x04
-#define HCI_LK_AUTH_COMBINATION		0x05
+#define HCI_LK_UNAUTH_COMBINATION_P192	0x04
+#define HCI_LK_AUTH_COMBINATION_P192	0x05
 #define HCI_LK_CHANGED_COMBINATION	0x06
+#define HCI_LK_UNAUTH_COMBINATION_P256	0x07
+#define HCI_LK_AUTH_COMBINATION_P256	0x08
 /* The spec doesn't define types for SMP keys, the _MASTER suffix is implied */
 #define HCI_SMP_STK			0x80
 #define HCI_SMP_STK_SLAVE		0x81
diff --git a/net/bluetooth/hci_conn.c b/net/bluetooth/hci_conn.c
index ba5366c320da..251f22e32fbf 100644
--- a/net/bluetooth/hci_conn.c
+++ b/net/bluetooth/hci_conn.c
@@ -802,12 +802,12 @@ int hci_conn_security(struct hci_conn *conn, __u8 sec_level, __u8 auth_type)
 
 	/* An authenticated combination key has sufficient security for any
 	   security level. */
-	if (conn->key_type == HCI_LK_AUTH_COMBINATION)
+	if (conn->key_type == HCI_LK_AUTH_COMBINATION_P192)
 		goto encrypt;
 
 	/* An unauthenticated combination key has sufficient security for
 	   security level 1 and 2. */
-	if (conn->key_type == HCI_LK_UNAUTH_COMBINATION &&
+	if (conn->key_type == HCI_LK_UNAUTH_COMBINATION_P192 &&
 	    (sec_level == BT_SECURITY_MEDIUM || sec_level == BT_SECURITY_LOW))
 		goto encrypt;
 
diff --git a/net/bluetooth/hci_event.c b/net/bluetooth/hci_event.c
index cfcce448957b..defa1252b534 100644
--- a/net/bluetooth/hci_event.c
+++ b/net/bluetooth/hci_event.c
@@ -2633,7 +2633,7 @@ static void hci_link_key_request_evt(struct hci_dev *hdev, struct sk_buff *skb)
 
 	conn = hci_conn_hash_lookup_ba(hdev, ACL_LINK, &ev->bdaddr);
 	if (conn) {
-		if (key->type == HCI_LK_UNAUTH_COMBINATION &&
+		if (key->type == HCI_LK_UNAUTH_COMBINATION_P192 &&
 		    conn->auth_type != 0xff && (conn->auth_type & 0x01)) {
 			BT_DBG("%s ignoring unauthenticated key", hdev->name);
 			goto not_found;
-- 
1.8.4.2


^ permalink raw reply related

* [PATCH v4 03/15] Bluetooth: Add HCI command definition for extended OOB data
From: Marcel Holtmann @ 2014-01-10 10:07 UTC (permalink / raw)
  To: linux-bluetooth

The Secure Connections feature introduces the support for P-256 strength
pairings (compared to P-192 with Secure Simple Pairing). This however
means that for out-of-band pairing the hash and randomizer needs to be
differentiated. Two new commands are introduced to handle the possible
combinations of P-192 and P-256. This add the HCI command definition
for both.

Signed-off-by: Marcel Holtmann <marcel@holtmann.org>
---
 include/net/bluetooth/hci.h | 18 ++++++++++++++++++
 1 file changed, 18 insertions(+)

diff --git a/include/net/bluetooth/hci.h b/include/net/bluetooth/hci.h
index 2a35d273de2c..e4e94bfc5232 100644
--- a/include/net/bluetooth/hci.h
+++ b/include/net/bluetooth/hci.h
@@ -664,6 +664,15 @@ struct hci_rp_set_csb {
 
 #define HCI_OP_START_SYNC_TRAIN		0x0443
 
+#define HCI_OP_REMOTE_OOB_EXT_DATA_REPLY	0x0445
+struct hci_cp_remote_oob_ext_data_reply {
+	bdaddr_t bdaddr;
+	__u8     hash192[16];
+	__u8     randomizer192[16];
+	__u8     hash256[16];
+	__u8     randomizer256[16];
+} __packed;
+
 #define HCI_OP_SNIFF_MODE		0x0803
 struct hci_cp_sniff_mode {
 	__le16   handle;
@@ -948,6 +957,15 @@ struct hci_cp_write_sc_support {
 	__u8	support;
 } __packed;
 
+#define HCI_OP_READ_LOCAL_OOB_EXT_DATA	0x0c7d
+struct hci_rp_read_local_oob_ext_data {
+	__u8     status;
+	__u8     hash192[16];
+	__u8     randomizer192[16];
+	__u8     hash256[16];
+	__u8     randomizer256[16];
+} __packed;
+
 #define HCI_OP_READ_LOCAL_VERSION	0x1001
 struct hci_rp_read_local_version {
 	__u8     status;
-- 
1.8.4.2


^ permalink raw reply related


This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox