]> granicus.if.org Git - esp-idf/commitdiff
NimBLE: Add optional mbedTLS support to NimBLE (backport)
authorPrasad Alatkar <prasad.alatkar@espressif.com>
Mon, 23 Sep 2019 13:37:40 +0000 (21:37 +0800)
committerJiang Jiang Jian <jack@espressif.com>
Mon, 23 Sep 2019 13:37:40 +0000 (21:37 +0800)
- NimBLE: Additional menuconfig option to enable mbedTLS instead of Tinycrypt from
  NimBLE, changes `component.mk` & `CMakeLists.txt` for the same.
- Addition of NimBLE stack size configuration and misc changes.
- mbedTLS: Addition of `CMAC` and `ECP_RESTARTABLE` to mbedTLS menuconfig option and
  `esp_config.h`.
- Example: Minor changes to `app_mesh.c` application.

13 files changed:
components/bt/CMakeLists.txt
components/bt/component.mk
components/bt/host/nimble/Kconfig.in
components/bt/host/nimble/nimble
components/bt/host/nimble/port/include/esp_nimble_cfg.h
components/mbedtls/Kconfig
components/mbedtls/mbedtls
components/mbedtls/port/include/mbedtls/esp_config.h
examples/bluetooth/nimble/blecent/blecent_test.py [moved from examples/bluetooth/nimble/blecent/blecent_test_noci.py with 98% similarity]
examples/bluetooth/nimble/blehr/blehr_test.py [moved from examples/bluetooth/nimble/blehr/blehr_test_noci.py with 59% similarity]
examples/bluetooth/nimble/blemesh/main/app_mesh.c
examples/bluetooth/nimble/bleprph/bleprph_test.py [moved from examples/bluetooth/nimble/bleprph/bleprph_test_noci.py with 56% similarity]
tools/ble/lib_ble_client.py

index 2b8a96363d0819aed7f7981a4138f91fdf31ad7a..d9cae26f124d092039073746607a5ec21e1966f3 100644 (file)
@@ -377,9 +377,13 @@ if(CONFIG_BT_ENABLED)
                     host/nimble/nimble/nimble/host/store/ram/include
                     host/nimble/nimble/nimble/host/store/config/include
                     host/nimble/nimble/porting/npl/freertos/include
-                    host/nimble/nimble/ext/tinycrypt/include
                     host/nimble/esp-hci/include)
 
+    if(NOT CONFIG_BT_NIMBLE_CRYPTO_STACK_MBEDTLS)
+
+        list(APPEND include_dirs
+                    host/nimble/nimble/ext/tinycrypt/include)
+
         list(APPEND srcs "host/nimble/nimble/ext/tinycrypt/src/utils.c"
                     "host/nimble/nimble/ext/tinycrypt/src/sha256.c"
                     "host/nimble/nimble/ext/tinycrypt/src/ecc.c"
@@ -394,8 +398,10 @@ if(CONFIG_BT_ENABLED)
                     "host/nimble/nimble/ext/tinycrypt/src/hmac_prng.c"
                     "host/nimble/nimble/ext/tinycrypt/src/ecc_platform_specific.c"
                     "host/nimble/nimble/ext/tinycrypt/src/hmac.c"
-                    "host/nimble/nimble/ext/tinycrypt/src/cbc_mode.c"
-                    "host/nimble/nimble/nimble/host/util/src/addr.c"
+                    "host/nimble/nimble/ext/tinycrypt/src/cbc_mode.c")
+    endif()
+
+        list(APPEND srcs "host/nimble/nimble/nimble/host/util/src/addr.c"
                     "host/nimble/nimble/nimble/host/services/gatt/src/ble_svc_gatt.c"
                     "host/nimble/nimble/nimble/host/services/tps/src/ble_svc_tps.c"
                     "host/nimble/nimble/nimble/host/services/ias/src/ble_svc_ias.c"
index 7fa74dcf03a16552b89de8adb2c29b00cc9dbf03..da70ea45a117c405c2ec22a73f488ecf2011b382 100644 (file)
@@ -148,11 +148,12 @@ ifdef CONFIG_BLE_MESH
                             esp_ble_mesh/mesh_models/common      \
                             esp_ble_mesh/mesh_models/client      \
                             esp_ble_mesh/api/core                \
-                            esp_ble_mesh/api/models 
+                            esp_ble_mesh/api/models
 endif
 
 
 ifdef CONFIG_BT_NIMBLE_ENABLED
+
 COMPONENT_ADD_INCLUDEDIRS += host/nimble/nimble/nimble/include                     \
                              host/nimble/nimble/nimble/host/include                \
                              host/nimble/nimble/porting/nimble/include             \
@@ -167,14 +168,16 @@ COMPONENT_ADD_INCLUDEDIRS += host/nimble/nimble/nimble/include
                              host/nimble/nimble/nimble/host/util/include           \
                              host/nimble/nimble/nimble/host/store/ram/include      \
                              host/nimble/nimble/nimble/host/store/config/include   \
-                             host/nimble/nimble/ext/tinycrypt/include              \
                              host/nimble/esp-hci/include                           \
                              host/nimble/port/include
 
+ifndef CONFIG_BT_NIMBLE_CRYPTO_STACK_MBEDTLS
+COMPONENT_ADD_INCLUDEDIRS += host/nimble/nimble/ext/tinycrypt/include
+endif
+
 COMPONENT_SRCDIRS += host/nimble/nimble/nimble/host/src                            \
                      host/nimble/nimble/porting/nimble/src                         \
                      host/nimble/nimble/porting/npl/freertos/src                   \
-                     host/nimble/nimble/ext/tinycrypt/src                          \
                      host/nimble/nimble/nimble/host/services/ans/src               \
                      host/nimble/nimble/nimble/host/services/bas/src               \
                      host/nimble/nimble/nimble/host/services/gap/src               \
@@ -187,6 +190,10 @@ COMPONENT_SRCDIRS += host/nimble/nimble/nimble/host/src
                      host/nimble/nimble/nimble/host/store/config/src               \
                      host/nimble/esp-hci/src
 
+ifndef CONFIG_BT_NIMBLE_CRYPTO_STACK_MBEDTLS
+COMPONENT_SRCDIRS += host/nimble/nimble/ext/tinycrypt/src
+endif
+
 COMPONENT_OBJEXCLUDE += host/nimble/nimble/nimble/host/store/config/src/ble_store_config_conf.o
 
 ifdef CONFIG_BT_NIMBLE_MESH
index 2fcbf91c7899e0a9db60c264e7534921a04b3c26..c469323ba81537392e4b08097012faf86ce06ba6 100644 (file)
@@ -50,6 +50,13 @@ config BT_NIMBLE_PINNED_TO_CORE
     default 1 if BT_NIMBLE_PINNED_TO_CORE_1
     default 0
 
+config BT_NIMBLE_TASK_STACK_SIZE
+    int "NimBLE Host task stack size"
+    depends on BT_NIMBLE_ENABLED
+    default 4096
+    help
+        This configures stack size of NimBLE host task
+
 config BT_NIMBLE_ROLE_CENTRAL
     bool "Enable BLE Central role"
     depends on BT_NIMBLE_ENABLED
@@ -92,11 +99,11 @@ config BT_NIMBLE_SM_SC
         Enable security manager secure connections
 
 config BT_NIMBLE_DEBUG
-    bool "Enable host debugging"
+    bool "Enable extra runtime asserts and host debugging"
     default n
     depends on BT_NIMBLE_ENABLED
     help
-        This enables extra runtime assertions
+        This enables extra runtime asserts and host debugging
 
 config BT_NIMBLE_SVC_GAP_DEVICE_NAME
     string "BLE GAP default device name"
@@ -250,3 +257,12 @@ config BT_NIMBLE_MESH_DEVICE_NAME
     help
         This value defines Bluetooth Mesh device/node name
 
+config BT_NIMBLE_CRYPTO_STACK_MBEDTLS
+    bool "Override TinyCrypt with mbedTLS for crypto computations"
+    default y
+    depends on BT_NIMBLE_ENABLED
+    select MBEDTLS_ECP_RESTARTABLE
+    select MBEDTLS_CMAC_C
+    help
+        Enable this option to choose mbedTLS instead of TinyCrypt for crypto
+        computations.
index 7600a6f60308c77fec755a024d51ab2fb7d11553..6c91a9a153c421231b686d30c822e53fea7510c0 160000 (submodule)
@@ -1 +1 @@
-Subproject commit 7600a6f60308c77fec755a024d51ab2fb7d11553
+Subproject commit 6c91a9a153c421231b686d30c822e53fea7510c0
index 7b9da7521768e8b2684bbc78f6bdca92fd7b2e72..c0b329c465aecf377fc90556e40da0355c1e476a 100644 (file)
 #define MYNEWT_VAL_BLE_SM_THEIR_KEY_DIST (0)
 #endif
 
+#ifndef MYNEWT_VAL_BLE_CRYPTO_STACK_MBEDTLS
+#define MYNEWT_VAL_BLE_CRYPTO_STACK_MBEDTLS (CONFIG_BT_NIMBLE_CRYPTO_STACK_MBEDTLS)
+#endif
+
 #ifndef MYNEWT_VAL_BLE_STORE_MAX_BONDS
 #define MYNEWT_VAL_BLE_STORE_MAX_BONDS CONFIG_BT_NIMBLE_MAX_BONDS
 #endif
index e597af28248704333166641d3c28778dee084282..596f97d9caf4c79097bc55752588d9aefad51782 100644 (file)
@@ -116,6 +116,19 @@ menu "mbedTLS"
         default 3 if MBEDTLS_DEBUG_LEVEL_DEBUG
         default 4 if MBEDTLS_DEBUG_LEVEL_VERBOSE
 
+    config MBEDTLS_ECP_RESTARTABLE
+        bool "Enable mbedTLS ecp restartable"
+        default n
+        help
+            Enable "non-blocking" ECC operations that can return early and be resumed.
+
+    config MBEDTLS_CMAC_C
+        bool "Enable CMAC mode for block ciphers"
+        default n
+        help
+            Enable the CMAC (Cipher-based Message Authentication Code) mode for
+            block ciphers.
+
     config MBEDTLS_HARDWARE_AES
         bool "Enable hardware AES acceleration"
         default y
index 97959e77912524bd8db7cbb2e00fc9f6189f7a82..f5f2e5926cd294ae7cb579ff6a12ad9303caeb6e 160000 (submodule)
@@ -1 +1 @@
-Subproject commit 97959e77912524bd8db7cbb2e00fc9f6189f7a82
+Subproject commit f5f2e5926cd294ae7cb579ff6a12ad9303caeb6e
index bdb9bf61a78bc8c20d300643dbf14da829337f83..d971ab8db405a2bfb6a360b46ae37c2256e5bee4 100644 (file)
 
 /**
  * \def MBEDTLS_REMOVE_ARC4_CIPHERSUITES & MBEDTLS_ARC4_C
- * 
+ *
  * MBEDTLS_ARC4_C
  * Enable the ARCFOUR stream cipher.
  *
 #define MBEDTLS_REMOVE_ARC4_CIPHERSUITES
 #endif
 
+/**
+ * \def MBEDTLS_ECP_RESTARTABLE
+ *
+ * Enable "non-blocking" ECC operations that can return early and be resumed.
+ *
+ * This allows various functions to pause by returning
+ * #MBEDTLS_ERR_ECP_IN_PROGRESS (or, for functions in the SSL module,
+ * #MBEDTLS_ERR_SSL_CRYPTO_IN_PROGRESS) and then be called later again in
+ * order to further progress and eventually complete their operation. This is
+ * controlled through mbedtls_ecp_set_max_ops() which limits the maximum
+ * number of ECC operations a function may perform before pausing; see
+ * mbedtls_ecp_set_max_ops() for more information.
+ *
+ * This is useful in non-threaded environments if you want to avoid blocking
+ * for too long on ECC (and, hence, X.509 or SSL/TLS) operations.
+ *
+ * Uncomment this macro to enable restartable ECC computations.
+ *
+ * \note  This option only works with the default software implementation of
+ *        elliptic curve functionality. It is incompatible with
+ *        MBEDTLS_ECP_ALT, MBEDTLS_ECDH_XXX_ALT and MBEDTLS_ECDSA_XXX_ALT.
+ */
+#ifdef CONFIG_MBEDTLS_ECP_RESTARTABLE
+#define MBEDTLS_ECP_RESTARTABLE
+#endif
+
+/**
+ * \def MBEDTLS_CMAC_C
+ *
+ * Enable the CMAC (Cipher-based Message Authentication Code) mode for block
+ * ciphers.
+ *
+ * Module:  library/cmac.c
+ *
+ * Requires: MBEDTLS_AES_C or MBEDTLS_DES_C
+ *
+ */
+#ifdef CONFIG_MBEDTLS_CMAC_C
+#define MBEDTLS_CMAC_C
+#endif
+
 /**
  * \def MBEDTLS_ECP_DP_SECP192R1_ENABLED
  *
similarity index 98%
rename from examples/bluetooth/nimble/blecent/blecent_test_noci.py
rename to examples/bluetooth/nimble/blecent/blecent_test.py
index d1d79298c413aee46b14bcf8fd73b04648a3cbe7..0933a71e2d50edf44d727bcf20f1cd653428ffb7 100644 (file)
@@ -64,6 +64,8 @@ def test_example_app_ble_central(env, extra_data):
     adv_type = 'peripheral'
     adv_uuid = '1811'
 
+    subprocess.check_output(['rm','-rf','/var/lib/bluetooth/*'])
+    subprocess.check_output(['hciconfig','hci0','reset'])
     # Acquire DUT
     dut = env.get_dut("blecent", "examples/bluetooth/nimble/blecent")
 
@@ -75,8 +77,8 @@ def test_example_app_ble_central(env, extra_data):
     # Upload binary and start testing
     Utility.console_log("Starting blecent example test app")
     dut.start_app()
+    dut.reset()
 
-    subprocess.check_output(['rm','-rf','/var/lib/bluetooth/*'])
     device_addr = ':'.join(re.findall('..', '%012x' % uuid.getnode()))
 
     # Get BLE client module
similarity index 59%
rename from examples/bluetooth/nimble/blehr/blehr_test_noci.py
rename to examples/bluetooth/nimble/blehr/blehr_test.py
index 81f21ee92ba8664780d0546dc1d6651d630a987c..7cc10ed889d4b84009a9aa72449eede1dfeb9517 100644 (file)
@@ -18,7 +18,9 @@ from __future__ import print_function
 import os
 import sys
 import re
-from threading import Thread
+import threading
+import traceback
+import Queue
 import subprocess
 
 try:
@@ -51,7 +53,7 @@ import Utility
 # > export TEST_FW_PATH=~/esp/esp-idf/tools/tiny-test-fw
 
 
-def blehr_client_task(dut_addr, dut):
+def blehr_client_task(hr_obj, dut_addr):
     interface = 'hci0'
     ble_devname = 'blehr_sensor_1.0'
     hr_srv_uuid = '180d'
@@ -70,20 +72,18 @@ def blehr_client_task(dut_addr, dut):
     # Connect BLE Device
     is_connected = ble_client_obj.connect()
     if not is_connected:
-        Utility.console_log("Connection to device ", ble_devname, "failed !!")
         # Call disconnect to perform cleanup operations before exiting application
         ble_client_obj.disconnect()
-        return
+        raise RuntimeError("Connection to device " + str(ble_devname) + " failed !!")
 
     # Read Services
     services_ret = ble_client_obj.get_services()
     if services_ret:
-        print("\nServices\n")
-        print(services_ret)
+        Utility.console_log("\nServices\n")
+        Utility.console_log(str(services_ret))
     else:
-        print("Failure: Read Services failed")
         ble_client_obj.disconnect()
-        return
+        raise RuntimeError("Failure: Read Services failed")
 
     '''
     Blehr application run:
@@ -93,14 +93,27 @@ def blehr_client_task(dut_addr, dut):
     '''
     blehr_ret = ble_client_obj.hr_update_simulation(hr_srv_uuid, hr_char_uuid)
     if blehr_ret:
-        print("Success: blehr example test passed")
+        Utility.console_log("Success: blehr example test passed")
     else:
-        print("Failure: blehr example test failed")
+        raise RuntimeError("Failure: blehr example test failed")
 
     # Call disconnect to perform cleanup operations before exiting application
     ble_client_obj.disconnect()
 
 
+class BleHRThread(threading.Thread):
+    def __init__(self, dut_addr, exceptions_queue):
+        threading.Thread.__init__(self)
+        self.dut_addr = dut_addr
+        self.exceptions_queue = exceptions_queue
+
+    def run(self):
+        try:
+            blehr_client_task(self, self.dut_addr)
+        except Exception:
+            self.exceptions_queue.put(traceback.format_exc(), block=False)
+
+
 @IDF.idf_example_test(env_tag="Example_WIFI_BT")
 def test_example_app_ble_hr(env, extra_data):
     """
@@ -111,38 +124,47 @@ def test_example_app_ble_hr(env, extra_data):
             4. Updated value is retrieved
             5. Stop Notifications
     """
-    try:
-        # Acquire DUT
-        dut = env.get_dut("blehr", "examples/bluetooth/nimble/blehr")
-
-        # Get binary file
-        binary_file = os.path.join(dut.app.binary_path, "blehr.bin")
-        bin_size = os.path.getsize(binary_file)
-        IDF.log_performance("blehr_bin_size", "{}KB".format(bin_size // 1024))
-        IDF.check_performance("blehr_bin_size", bin_size // 1024)
-
-        # Upload binary and start testing
-        Utility.console_log("Starting blehr simple example test app")
-        dut.start_app()
-
-        subprocess.check_output(['rm','-rf','/var/lib/bluetooth/*'])
-
-        # Get device address from dut
-        dut_addr = dut.expect(re.compile(r"Device Address: ([a-fA-F0-9:]+)"), timeout=30)[0]
-
-        # Starting a py-client in a separate thread
-        thread1 = Thread(target=blehr_client_task, args=(dut_addr,dut,))
-        thread1.start()
-        thread1.join()
-
-        # Check dut responses
-        dut.expect("subscribe event; cur_notify=1", timeout=30)
-        dut.expect("GATT procedure initiated: notify;", timeout=30)
-        dut.expect("subscribe event; cur_notify=0", timeout=30)
-        dut.expect("disconnect;", timeout=30)
-
-    except Exception as e:
-        sys.exit(e)
+    subprocess.check_output(['rm','-rf','/var/lib/bluetooth/*'])
+    subprocess.check_output(['hciconfig','hci0','reset'])
+
+    # Acquire DUT
+    dut = env.get_dut("blehr", "examples/bluetooth/nimble/blehr")
+
+    # Get binary file
+    binary_file = os.path.join(dut.app.binary_path, "blehr.bin")
+    bin_size = os.path.getsize(binary_file)
+    IDF.log_performance("blehr_bin_size", "{}KB".format(bin_size // 1024))
+    IDF.check_performance("blehr_bin_size", bin_size // 1024)
+
+    # Upload binary and start testing
+    Utility.console_log("Starting blehr simple example test app")
+    dut.start_app()
+    dut.reset()
+
+    # Get device address from dut
+    dut_addr = dut.expect(re.compile(r"Device Address: ([a-fA-F0-9:]+)"), timeout=30)[0]
+    exceptions_queue = Queue.Queue()
+    # Starting a py-client in a separate thread
+    blehr_thread_obj = BleHRThread(dut_addr, exceptions_queue)
+    blehr_thread_obj.start()
+    blehr_thread_obj.join()
+
+    exception_msg = None
+    while True:
+        try:
+            exception_msg = exceptions_queue.get(block=False)
+        except Queue.Empty:
+            break
+        else:
+            Utility.console_log("\n" + exception_msg)
+
+    if exception_msg:
+        raise Exception("Thread did not run successfully")
+
+    # Check dut responses
+    dut.expect("subscribe event; cur_notify=1", timeout=30)
+    dut.expect("subscribe event; cur_notify=0", timeout=30)
+    dut.expect("disconnect;", timeout=30)
 
 
 if __name__ == '__main__':
index 69101926587772e80994648b434e892e1e15b0cf..3a5609d3b0323017ee2b03d9f71aa11391ba631e 100644 (file)
@@ -32,7 +32,7 @@
 #include "mesh/mesh.h"
 
 static const char *tag = "NimBLE_MESH";
-void ble_store_ram_init(void);
+void ble_store_config_init(void);
 
 #define BT_DBG_ENABLED (MYNEWT_VAL(BLE_MESH_DEBUG))
 
@@ -418,6 +418,7 @@ void blemesh_host_task(void *param)
 
     health_pub_init();
     nimble_port_run();
+    nimble_port_freertos_deinit();
 }
 
 void app_main()
@@ -438,7 +439,7 @@ void app_main()
 
     bt_mesh_register_gatt();
     /* XXX Need to have template for store */
-    ble_store_ram_init();
+    ble_store_config_init();
 
     nimble_port_freertos_init(blemesh_host_task);
 }
similarity index 56%
rename from examples/bluetooth/nimble/bleprph/bleprph_test_noci.py
rename to examples/bluetooth/nimble/bleprph/bleprph_test.py
index 3e29f668c21796906fbe9cdf4a299c07a6f5f58c..97bfeca97a055e829e601bece083251362a86ce7 100644 (file)
@@ -18,7 +18,9 @@ from __future__ import print_function
 import os
 import sys
 import re
-from threading import Thread
+import Queue
+import traceback
+import threading
 import subprocess
 
 try:
@@ -50,7 +52,7 @@ import Utility
 # > export TEST_FW_PATH=~/esp/esp-idf/tools/tiny-test-fw
 
 
-def bleprph_client_task(dut_addr, dut):
+def bleprph_client_task(prph_obj, dut, dut_addr):
     interface = 'hci0'
     ble_devname = 'nimble-bleprph'
     srv_uuid = '2f12'
@@ -68,10 +70,9 @@ def bleprph_client_task(dut_addr, dut):
     # Connect BLE Device
     is_connected = ble_client_obj.connect()
     if not is_connected:
-        Utility.console_log("Connection to device ", ble_devname, "failed !!")
         # Call disconnect to perform cleanup operations before exiting application
         ble_client_obj.disconnect()
-        return
+        raise RuntimeError("Connection to device " + ble_devname + " failed !!")
 
     # Check dut responses
     dut.expect("GAP procedure initiated: advertise;", timeout=30)
@@ -79,12 +80,11 @@ def bleprph_client_task(dut_addr, dut):
     # Read Services
     services_ret = ble_client_obj.get_services(srv_uuid)
     if services_ret:
-        print("\nServices\n")
-        print(services_ret)
+        Utility.console_log("\nServices\n")
+        Utility.console_log(str(services_ret))
     else:
-        print("Failure: Read Services failed")
         ble_client_obj.disconnect()
-        return
+        raise RuntimeError("Failure: Read Services failed")
 
     # Read Characteristics
     chars_ret = {}
@@ -92,14 +92,13 @@ def bleprph_client_task(dut_addr, dut):
     if chars_ret:
         Utility.console_log("\nCharacteristics retrieved")
         for path, props in chars_ret.items():
-            print("\n\tCharacteristic: ", path)
-            print("\tCharacteristic UUID: ", props[2])
-            print("\tValue: ", props[0])
-            print("\tProperties: : ", props[1])
+            Utility.console_log("\n\tCharacteristic: " + str(path))
+            Utility.console_log("\tCharacteristic UUID: " + str(props[2]))
+            Utility.console_log("\tValue: " + str(props[0]))
+            Utility.console_log("\tProperties: : " + str(props[1]))
     else:
-        print("Failure: Read Characteristics failed")
         ble_client_obj.disconnect()
-        return
+        raise RuntimeError("Failure: Read Characteristics failed")
 
     '''
     Write Characteristics
@@ -110,19 +109,32 @@ def bleprph_client_task(dut_addr, dut):
     if chars_ret_on_write:
         Utility.console_log("\nCharacteristics after write operation")
         for path, props in chars_ret_on_write.items():
-            print("\n\tCharacteristic:", path)
-            print("\tCharacteristic UUID: ", props[2])
-            print("\tValue:", props[0])
-            print("\tProperties: : ", props[1])
+            Utility.console_log("\n\tCharacteristic:" + str(path))
+            Utility.console_log("\tCharacteristic UUID: " + str(props[2]))
+            Utility.console_log("\tValue:" + str(props[0]))
+            Utility.console_log("\tProperties: : " + str(props[1]))
     else:
-        print("Failure: Write Characteristics failed")
         ble_client_obj.disconnect()
-        return
+        raise RuntimeError("Failure: Write Characteristics failed")
 
     # Call disconnect to perform cleanup operations before exiting application
     ble_client_obj.disconnect()
 
 
+class BlePrphThread(threading.Thread):
+    def __init__(self, dut, dut_addr, exceptions_queue):
+        threading.Thread.__init__(self)
+        self.dut = dut
+        self.dut_addr = dut_addr
+        self.exceptions_queue = exceptions_queue
+
+    def run(self):
+        try:
+            bleprph_client_task(self, self.dut, self.dut_addr)
+        except Exception:
+            self.exceptions_queue.put(traceback.format_exc(), block=False)
+
+
 @IDF.idf_example_test(env_tag="Example_WIFI_BT")
 def test_example_app_ble_peripheral(env, extra_data):
     """
@@ -133,36 +145,47 @@ def test_example_app_ble_peripheral(env, extra_data):
             4. Read Characteristics
             5. Write Characteristics
     """
-    try:
-
-        # Acquire DUT
-        dut = env.get_dut("bleprph", "examples/bluetooth/nimble/bleprph")
-
-        # Get binary file
-        binary_file = os.path.join(dut.app.binary_path, "bleprph.bin")
-        bin_size = os.path.getsize(binary_file)
-        IDF.log_performance("bleprph_bin_size", "{}KB".format(bin_size // 1024))
-        IDF.check_performance("bleprph_bin_size", bin_size // 1024)
+    subprocess.check_output(['rm','-rf','/var/lib/bluetooth/*'])
+    subprocess.check_output(['hciconfig','hci0','reset'])
+
+    # Acquire DUT
+    dut = env.get_dut("bleprph", "examples/bluetooth/nimble/bleprph")
+
+    # Get binary file
+    binary_file = os.path.join(dut.app.binary_path, "bleprph.bin")
+    bin_size = os.path.getsize(binary_file)
+    IDF.log_performance("bleprph_bin_size", "{}KB".format(bin_size // 1024))
+    IDF.check_performance("bleprph_bin_size", bin_size // 1024)
+
+    # Upload binary and start testing
+    Utility.console_log("Starting bleprph simple example test app")
+    dut.start_app()
+    dut.reset()
+
+    # Get device address from dut
+    dut_addr = dut.expect(re.compile(r"Device Address: ([a-fA-F0-9:]+)"), timeout=30)[0]
+
+    exceptions_queue = Queue.Queue()
+    # Starting a py-client in a separate thread
+    bleprph_thread_obj = BlePrphThread(dut, dut_addr, exceptions_queue)
+    bleprph_thread_obj.start()
+    bleprph_thread_obj.join()
+
+    exception_msg = None
+    while True:
+        try:
+            exception_msg = exceptions_queue.get(block=False)
+        except Queue.Empty:
+            break
+        else:
+            Utility.console_log("\n" + exception_msg)
+
+    if exception_msg:
+        raise Exception("Thread did not run successfully")
 
-        # Upload binary and start testing
-        Utility.console_log("Starting bleprph simple example test app")
-        dut.start_app()
-
-        subprocess.check_output(['rm','-rf','/var/lib/bluetooth/*'])
-
-        # Get device address from dut
-        dut_addr = dut.expect(re.compile(r"Device Address: ([a-fA-F0-9:]+)"), timeout=30)[0]
-
-        # Starting a py-client in a separate thread
-        thread1 = Thread(target=bleprph_client_task, args=(dut_addr,dut,))
-        thread1.start()
-        thread1.join()
-
-        # Check dut responses
-        dut.expect("connection established; status=0", timeout=30)
-        dut.expect("disconnect;", timeout=30)
-    except Exception as e:
-        sys.exit(e)
+    # Check dut responses
+    dut.expect("connection established; status=0", timeout=30)
+    dut.expect("disconnect;", timeout=30)
 
 
 if __name__ == '__main__':
index 3cbec037098acfda611637b73946722688863933..6fda14288c94928976454df3f975f788e42a2020 100644 (file)
@@ -20,6 +20,7 @@
 from __future__ import print_function
 import sys
 import time
+import traceback
 
 try:
     from future.moves.itertools import zip_longest
@@ -39,11 +40,11 @@ import lib_gap
 
 srv_added_old_cnt = 0
 srv_added_new_cnt = 0
+verify_signal_check = 0
 blecent_retry_check_cnt = 0
 verify_service_cnt = 0
 verify_readchars_cnt = 0
 blecent_adv_uuid = '1811'
-iface_added = False
 gatt_app_obj_check = False
 gatt_app_reg_check = False
 adv_data_check = False
@@ -54,6 +55,7 @@ subscribe_req_check = False
 ble_hr_chrc = False
 
 DISCOVERY_START = False
+SIGNAL_CAUGHT = False
 
 TEST_CHECKS_PASS = False
 ADV_STOP = False
@@ -89,26 +91,42 @@ dbus.mainloop.glib.threads_init()
 event_loop = GLib.MainLoop()
 
 
+def verify_signal_is_caught():
+    global verify_signal_check
+    verify_signal_check += 1
+
+    if (not SIGNAL_CAUGHT and verify_signal_check == 15) or (SIGNAL_CAUGHT):
+        if event_loop.is_running():
+            event_loop.quit()
+            return False  # polling for checks will stop
+
+    return True  # polling will continue
+
+
 def set_props_status(props):
     """
         Set Adapter status if it is powered on or off
     """
     global ADAPTER_ON, SERVICES_RESOLVED, GATT_OBJ_REMOVED, GATT_APP_REGISTERED, \
-        ADV_REGISTERED, ADV_ACTIVE_INSTANCE, DEVICE_CONNECTED, CHRC_VALUE, CHRC_VALUE_CNT
+        ADV_REGISTERED, ADV_ACTIVE_INSTANCE, DEVICE_CONNECTED, CHRC_VALUE, CHRC_VALUE_CNT, \
+        SIGNAL_CAUGHT
     is_service_uuid = False
     # Signal caught for change in Adapter Powered property
     if 'Powered' in props:
         if props['Powered'] == 1:
+            SIGNAL_CAUGHT = True
             ADAPTER_ON = True
         else:
+            SIGNAL_CAUGHT = True
             ADAPTER_ON = False
-        event_loop.quit()
-    elif 'ServicesResolved' in props:
+    if 'ServicesResolved' in props:
         if props['ServicesResolved'] == 1:
+            SIGNAL_CAUGHT = True
             SERVICES_RESOLVED = True
         else:
+            SIGNAL_CAUGHT = True
             SERVICES_RESOLVED = False
-    elif 'UUIDs' in props:
+    if 'UUIDs' in props:
         # Signal caught for add/remove GATT data having service uuid
         for uuid in props['UUIDs']:
             if blecent_adv_uuid in uuid:
@@ -118,7 +136,7 @@ def set_props_status(props):
             # and for unregistering GATT application
             GATT_APP_REGISTERED = False
             lib_gatt.GATT_APP_OBJ = False
-    elif 'ActiveInstances' in props:
+    if 'ActiveInstances' in props:
         # Signal caught for Advertising - add/remove Instances property
         if props['ActiveInstances'] == 1:
             ADV_ACTIVE_INSTANCE = True
@@ -126,20 +144,24 @@ def set_props_status(props):
             ADV_ACTIVE_INSTANCE = False
             ADV_REGISTERED = False
             lib_gap.ADV_OBJ = False
-    elif 'Connected' in props:
+    if 'Connected' in props:
         # Signal caught for device connect/disconnect
-        if props['Connected'] is True:
+        if props['Connected'] == 1:
+            SIGNAL_CAUGHT = True
             DEVICE_CONNECTED = True
-            event_loop.quit()
         else:
+            SIGNAL_CAUGHT = True
             DEVICE_CONNECTED = False
-    elif 'Value' in props:
+    if 'Value' in props:
         # Signal caught for change in chars value
         if ble_hr_chrc:
             CHRC_VALUE_CNT += 1
             print(props['Value'])
             if CHRC_VALUE_CNT == 10:
-                event_loop.quit()
+                SIGNAL_CAUGHT = True
+                return False
+
+    return False
 
 
 def props_change_handler(iface, changed_props, invalidated):
@@ -194,6 +216,9 @@ class BLE_Bluez_Client:
             Discover Bluetooth Adapter
             Power On Bluetooth Adapter
         '''
+        global verify_signal_check, SIGNAL_CAUGHT, ADAPTER_ON
+        verify_signal_check = 0
+        ADAPTER_ON = False
         try:
             print("discovering adapter...")
             for path, interfaces in self.ble_objs.items():
@@ -209,45 +234,45 @@ class BLE_Bluez_Client:
                         break
 
             if self.adapter is None:
-                raise RuntimeError("\nError: bluetooth adapter not found")
+                raise Exception("Bluetooth adapter not found")
 
             if self.props_iface_obj is None:
-                raise RuntimeError("\nError: properties interface not found")
+                raise Exception("Properties interface not found")
 
             print("bluetooth adapter discovered")
 
-            self.props_iface_obj.connect_to_signal('PropertiesChanged', props_change_handler)
-
             # Check if adapter is already powered on
             if ADAPTER_ON:
-                print("bluetooth adapter is already on")
+                print("Adapter already powered on")
                 return True
 
             # Power On Adapter
             print("powering on adapter...")
+            self.props_iface_obj.connect_to_signal('PropertiesChanged', props_change_handler)
             self.props_iface_obj.Set(ADAPTER_IFACE, "Powered", dbus.Boolean(1))
 
+            SIGNAL_CAUGHT = False
+            GLib.timeout_add_seconds(5, verify_signal_is_caught)
             event_loop.run()
 
             if ADAPTER_ON:
                 print("bluetooth adapter powered on")
                 return True
             else:
-                print("Failure: bluetooth adapter not powered on")
-                return False
+                raise Exception("Failure: bluetooth adapter not powered on")
 
-        except Exception as e:
-            print(e)
-            sys.exit(1)
+        except Exception:
+            print(traceback.format_exc())
+            return False
 
     def connect(self):
         '''
             Connect to the device discovered
             Retry 10 times to discover and connect to device
         '''
-        global DISCOVERY_START
-
+        global DISCOVERY_START, SIGNAL_CAUGHT, DEVICE_CONNECTED, verify_signal_check
         device_found = False
+        DEVICE_CONNECTED = False
         try:
             self.adapter.StartDiscovery()
             print("\nStarted Discovery")
@@ -255,6 +280,7 @@ class BLE_Bluez_Client:
             DISCOVERY_START = True
 
             for retry_cnt in range(10,0,-1):
+                verify_signal_check = 0
                 try:
                     if self.device is None:
                         print("\nConnecting to device...")
@@ -263,9 +289,15 @@ class BLE_Bluez_Client:
                         device_found = self.get_device()
                     if device_found:
                         self.device.Connect(dbus_interface=DEVICE_IFACE)
-                        event_loop.quit()
-                        print("\nConnected to device")
-                        return True
+                        time.sleep(15)
+                        SIGNAL_CAUGHT = False
+                        GLib.timeout_add_seconds(5, verify_signal_is_caught)
+                        event_loop.run()
+                        if DEVICE_CONNECTED:
+                            print("\nConnected to device")
+                            return True
+                        else:
+                            raise Exception
                 except Exception as e:
                     print(e)
                     print("\nRetries left", retry_cnt - 1)
@@ -274,8 +306,8 @@ class BLE_Bluez_Client:
             # Device not found
             return False
 
-        except Exception as e:
-            print(e)
+        except Exception:
+            print(traceback.format_exc())
             self.device = None
             return False
 
@@ -299,8 +331,7 @@ class BLE_Bluez_Client:
                 break
 
         if dev_path is None:
-            print("\nBLE device not found")
-            return False
+            raise Exception("\nBLE device not found")
 
         device_props_iface_obj = dbus.Interface(self.bus.get_object(BLUEZ_SERVICE_NAME, dev_path), DBUS_PROP_IFACE)
         device_props_iface_obj.connect_to_signal('PropertiesChanged', props_change_handler)
@@ -321,16 +352,7 @@ class BLE_Bluez_Client:
                 if path not in self.services:
                     self.services.append(path)
 
-    def verify_get_services(self):
-        global SERVICE_SCAN_FAIL, verify_service_cnt
-        verify_service_cnt += 1
-        if iface_added and self.services and SERVICES_RESOLVED:
-            event_loop.quit()
-
-        if verify_service_cnt == 10:
-            event_loop.quit()
-
-    def verify_service_uuid_found(self):
+    def verify_service_uuid_found(self, service_uuid):
         '''
         Verify service uuid found
         '''
@@ -340,40 +362,45 @@ class BLE_Bluez_Client:
         if srv_uuid_found:
             SERVICE_UUID_FOUND = True
 
-    def get_services(self, srv_uuid=None):
+    def get_services(self, service_uuid=None):
         '''
         Retrieve Services found in the device connected
         '''
-        global service_uuid, iface_added, SERVICE_UUID_FOUND
-        service_uuid = srv_uuid
-        iface_added = False
+        global SIGNAL_CAUGHT, SERVICE_UUID_FOUND, SERVICES_RESOLVED, verify_signal_check
+        verify_signal_check = 0
         SERVICE_UUID_FOUND = False
+        SERVICES_RESOLVED = False
+        SIGNAL_CAUGHT = False
+
         try:
             om_iface_obj = dbus.Interface(self.bus.get_object(BLUEZ_SERVICE_NAME, "/"), DBUS_OM_IFACE)
             self.ble_objs = om_iface_obj.GetManagedObjects()
-
             for path, interfaces in self.ble_objs.items():
                 self.srvc_iface_added_handler(path, interfaces)
             # If services not found, then they may not have been added yet on dbus
             if not self.services:
-                iface_added = True
-                GLib.timeout_add_seconds(2, self.verify_get_services)
+                GLib.timeout_add_seconds(5, verify_signal_is_caught)
                 om_iface_obj.connect_to_signal('InterfacesAdded', self.srvc_iface_added_handler)
                 event_loop.run()
+                if not SERVICES_RESOLVED:
+                    raise Exception("Services not found...")
+
             if service_uuid:
-                self.verify_service_uuid_found()
+                self.verify_service_uuid_found(service_uuid)
                 if not SERVICE_UUID_FOUND:
-                    raise Exception("Service with uuid: %s not found !!!" % service_uuid)
+                    raise Exception("Service with uuid: %s not found..." % service_uuid)
+
+            # Services found
             return self.srv_uuid
-        except Exception as e:
-            print("Error: ", e)
+        except Exception:
+            print(traceback.format_exc())
             return False
 
     def chrc_iface_added_handler(self, path, interfaces):
         '''
         Add services found as lib_ble_client obj
         '''
-        global chrc, chrc_discovered
+        global chrc, chrc_discovered, SIGNAL_CAUGHT
         chrc_val = None
 
         if self.device and path.startswith(self.device.object_path):
@@ -386,22 +413,17 @@ class BLE_Bluez_Client:
                     chrc_val = chrc.ReadValue({}, dbus_interface=GATT_CHRC_IFACE)
                 uuid = chrc_props['UUID']
                 self.chars[path] = chrc_val, chrc_flags, uuid
-
-    def verify_get_chars(self):
-        global verify_readchars_cnt
-        verify_readchars_cnt += 1
-        if iface_added and self.chars:
-                event_loop.quit()
-        if verify_readchars_cnt == 10:
-            event_loop.quit()
+                SIGNAL_CAUGHT = True
 
     def read_chars(self):
         '''
             Read characteristics found in the device connected
         '''
-        global iface_added, chrc_discovered
+        global iface_added, chrc_discovered, SIGNAL_CAUGHT, verify_signal_check
+        verify_signal_check = 0
         chrc_discovered = False
         iface_added = False
+        SIGNAL_CAUGHT = False
 
         try:
             om_iface_obj = dbus.Interface(self.bus.get_object(BLUEZ_SERVICE_NAME, "/"), DBUS_OM_IFACE)
@@ -410,14 +432,15 @@ class BLE_Bluez_Client:
                 self.chrc_iface_added_handler(path, interfaces)
 
             # If chars not found, then they have not been added yet to interface
+            time.sleep(15)
             if not self.chars:
                 iface_added = True
-                GLib.timeout_add_seconds(2, self.verify_get_chars)
+                GLib.timeout_add_seconds(5, verify_signal_is_caught)
                 om_iface_obj.connect_to_signal('InterfacesAdded', self.chars_iface_added_handler)
                 event_loop.run()
             return self.chars
-        except Exception as e:
-            print("Error: ", e)
+        except Exception:
+            print(traceback.format_exc())
             return False
 
     def write_chars(self, write_val):
@@ -443,12 +466,11 @@ class BLE_Bluez_Client:
                         return False
                     self.chars[path] = chrc_val, props[1], props[2]  # update value
             if not char_write_props:
-                print("Failure: Cannot perform write operation. Characteristic does not have write permission.")
-                return False
+                raise Exception("Failure: Cannot perform write operation. Characteristic does not have write permission.")
 
             return self.chars
-        except Exception as e:
-            print(e)
+        except Exception:
+            print(traceback.format_exc())
             return False
 
     def hr_update_simulation(self, hr_srv_uuid, hr_char_uuid):
@@ -457,7 +479,7 @@ class BLE_Bluez_Client:
             Retrieve updated value
             Stop Notifications
         '''
-        global ble_hr_chrc
+        global ble_hr_chrc, verify_signal_check, SIGNAL_CAUGHT, CHRC_VALUE_CNT
 
         srv_path = None
         chrc = None
@@ -465,6 +487,7 @@ class BLE_Bluez_Client:
         chrc_path = None
         chars_ret = None
         ble_hr_chrc = True
+        CHRC_VALUE_CNT = 0
 
         try:
             # Get HR Measurement characteristic
@@ -475,8 +498,7 @@ class BLE_Bluez_Client:
                     break
 
             if srv_path is None:
-                print("Failure: HR UUID:", hr_srv_uuid, "not found")
-                return False
+                raise Exception("Failure: HR UUID:", hr_srv_uuid, "not found")
 
             chars_ret = self.read_chars()
 
@@ -487,8 +509,8 @@ class BLE_Bluez_Client:
                     if hr_char_uuid in props[2]:  # uuid
                         break
             if chrc is None:
-                print("Failure: Characteristics for service: ", srv_path, "not found")
-                return False
+                raise Exception("Failure: Characteristics for service: ", srv_path, "not found")
+
             # Subscribe to notifications
             print("\nSubscribe to notifications: On")
             chrc.StartNotify(dbus_interface=GATT_CHRC_IFACE)
@@ -496,6 +518,9 @@ class BLE_Bluez_Client:
             chrc_props_iface_obj = dbus.Interface(self.bus.get_object(BLUEZ_SERVICE_NAME, chrc_path), DBUS_PROP_IFACE)
             chrc_props_iface_obj.connect_to_signal('PropertiesChanged', props_change_handler)
 
+            SIGNAL_CAUGHT = False
+            verify_signal_check = 0
+            GLib.timeout_add_seconds(5, verify_signal_is_caught)
             event_loop.run()
             chrc.StopNotify(dbus_interface=GATT_CHRC_IFACE)
             time.sleep(2)
@@ -504,8 +529,8 @@ class BLE_Bluez_Client:
             ble_hr_chrc = False
             return True
 
-        except Exception as e:
-            print(e)
+        except Exception:
+            print(traceback.format_exc())
             return False
 
     def create_gatt_app(self):
@@ -513,10 +538,12 @@ class BLE_Bluez_Client:
             Create GATT data
             Register GATT Application
         '''
-        global gatt_app_obj, gatt_manager_iface_obj
+        global gatt_app_obj, gatt_manager_iface_obj, GATT_APP_REGISTERED
 
         gatt_app_obj = None
         gatt_manager_iface_obj = None
+        GATT_APP_REGISTERED = False
+        lib_gatt.GATT_APP_OBJ = False
 
         try:
             gatt_app_obj = lib_gatt.Application(self.bus, self.adapter_path[0])
@@ -526,8 +553,8 @@ class BLE_Bluez_Client:
                                                        reply_handler=self.gatt_app_handler,
                                                        error_handler=self.gatt_app_error_handler)
             return True
-        except Exception as e:
-            print(e)
+        except Exception:
+            print(traceback.format_exc())
             return False
 
     def gatt_app_handler(self):
@@ -550,25 +577,28 @@ class BLE_Bluez_Client:
             Register Advertisement
             Start Advertising
         '''
-        global le_adv_obj, le_adv_manager_iface_obj
+        global le_adv_obj, le_adv_manager_iface_obj, ADV_ACTIVE_INSTANCE, ADV_REGISTERED
+
         le_adv_obj = None
         le_adv_manager_iface_obj = None
         le_adv_iface_path = None
+        ADV_ACTIVE_INSTANCE = False
+        ADV_REGISTERED = False
+        lib_gap.ADV_OBJ = False
 
         try:
             print("Advertising started")
             gatt_app_ret = self.create_gatt_app()
 
             if not gatt_app_ret:
-                return False
+                raise Exception
 
             for path,interface in self.ble_objs.items():
                 if LE_ADVERTISING_MANAGER_IFACE in interface:
                     le_adv_iface_path = path
 
             if le_adv_iface_path is None:
-                print('\n Cannot start advertising. LEAdvertisingManager1 Interface not found')
-                return False
+                raise Exception('\n Cannot start advertising. LEAdvertisingManager1 Interface not found')
 
             le_adv_obj = lib_gap.Advertisement(self.bus, adv_iface_index, adv_type, adv_uuid, adv_host_name)
             le_adv_manager_iface_obj = dbus.Interface(self.bus.get_object(BLUEZ_SERVICE_NAME, le_adv_iface_path), LE_ADVERTISING_MANAGER_IFACE)
@@ -583,11 +613,10 @@ class BLE_Bluez_Client:
             if TEST_CHECKS_PASS:
                 return True
             else:
-                return False
+                raise Exception
 
-        except Exception as e:
-            print("in Exception")
-            print(e)
+        except Exception:
+            print(traceback.format_exc())
             return False
 
     def adv_handler(self):
@@ -646,39 +675,41 @@ class BLE_Bluez_Client:
             TEST_CHECKS_PASS = False
             if subscribe_req_check:
                 lib_gatt.alert_status_char_obj.StopNotify()
-            event_loop.quit()
-            return False  # polling for checks will stop
-
-        # Check for success
-        if not gatt_app_obj_check and lib_gatt.GATT_APP_OBJ:
-            print("GATT Data created")
-            gatt_app_obj_check = True
-        if not gatt_app_reg_check and GATT_APP_REGISTERED:
-            print("GATT Application registered")
-            gatt_app_reg_check = True
-        if not adv_data_check and lib_gap.ADV_OBJ:
-            print("Advertising data created")
-            adv_data_check = True
-        if not adv_reg_check and ADV_REGISTERED and ADV_ACTIVE_INSTANCE:
-            print("Advertisement registered")
-            adv_reg_check = True
-        if not read_req_check and lib_gatt.CHAR_READ:
-            read_req_check = True
-        if not write_req_check and lib_gatt.CHAR_WRITE:
-            write_req_check = True
-        if not subscribe_req_check and lib_gatt.CHAR_SUBSCRIBE:
-            subscribe_req_check = True
+        else:
+            # Check for success
+            if not gatt_app_obj_check and lib_gatt.GATT_APP_OBJ:
+                print("GATT Data created")
+                gatt_app_obj_check = True
+            if not gatt_app_reg_check and GATT_APP_REGISTERED:
+                print("GATT Application registered")
+                gatt_app_reg_check = True
+            if not adv_data_check and lib_gap.ADV_OBJ:
+                print("Advertising data created")
+                adv_data_check = True
+            if not adv_reg_check and ADV_REGISTERED and ADV_ACTIVE_INSTANCE:
+                print("Advertisement registered")
+                adv_reg_check = True
+            if not read_req_check and lib_gatt.CHAR_READ:
+                read_req_check = True
+            if not write_req_check and lib_gatt.CHAR_WRITE:
+                write_req_check = True
+            if not subscribe_req_check and lib_gatt.CHAR_SUBSCRIBE:
+                subscribe_req_check = True
 
-        # Increment retry count
-        blecent_retry_check_cnt += 1
         if read_req_check and write_req_check and subscribe_req_check:
             # all checks passed
             # Blecent Test passed
             TEST_CHECKS_PASS = True
             lib_gatt.alert_status_char_obj.StopNotify()
-            event_loop.quit()
+
+        if (blecent_retry_check_cnt == 10 or TEST_CHECKS_PASS):
+            if event_loop.is_running():
+                event_loop.quit()
             return False  # polling for checks will stop
 
+        # Increment retry count
+        blecent_retry_check_cnt += 1
+
         # Default return True - polling for checks will continue
         return True
 
@@ -709,29 +740,29 @@ class BLE_Bluez_Client:
 
             # Blecent Test failed
             ADV_STOP = False
-            event_loop.quit()
+        else:
+            # Check for success
+            if not gatt_app_obj_check and not lib_gatt.GATT_APP_OBJ:
+                print("GATT Data removed")
+                gatt_app_obj_check = True
+            if not gatt_app_reg_check and not GATT_APP_REGISTERED:
+                print("GATT Application unregistered")
+                gatt_app_reg_check = True
+            if not adv_data_check and not adv_reg_check and not (ADV_REGISTERED or ADV_ACTIVE_INSTANCE or lib_gap.ADV_OBJ):
+                print("Advertising data removed")
+                print("Advertisement unregistered")
+                adv_data_check = True
+                adv_reg_check = True
+                # all checks passed
+                ADV_STOP = True
+
+        if (blecent_retry_check_cnt == 10 or ADV_STOP):
+            if event_loop.is_running():
+                event_loop.quit()
             return False  # polling for checks will stop
 
-        # Check for success
-        if not gatt_app_obj_check and not lib_gatt.GATT_APP_OBJ:
-            print("GATT Data removed")
-            gatt_app_obj_check = True
-        if not gatt_app_reg_check and not GATT_APP_REGISTERED:
-            print("GATT Application unregistered")
-            gatt_app_reg_check = True
-        if not adv_data_check and not adv_reg_check and not (ADV_REGISTERED or ADV_ACTIVE_INSTANCE or lib_gap.ADV_OBJ):
-            print("Advertising data removed")
-            print("Advertisement unregistered")
-            adv_data_check = True
-            adv_reg_check = True
-
         # Increment retry count
         blecent_retry_check_cnt += 1
-        if adv_reg_check:
-            # all checks passed
-            ADV_STOP = True
-            event_loop.quit()
-            return False  # polling for checks will stop
 
         # Default return True - polling for checks will continue
         return True
@@ -747,11 +778,14 @@ class BLE_Bluez_Client:
             Adapter is powered off
         '''
         try:
-            global blecent_retry_check_cnt, DISCOVERY_START
+            global blecent_retry_check_cnt, DISCOVERY_START, verify_signal_check, SIGNAL_CAUGHT
             blecent_retry_check_cnt = 0
+            verify_signal_check = 0
 
             print("\nexiting from test...")
 
+            self.props_iface_obj.connect_to_signal('PropertiesChanged', props_change_handler)
+
             if ADV_REGISTERED:
                 # Unregister Advertisement
                 le_adv_manager_iface_obj.UnregisterAdvertisement(le_adv_obj.get_path())
@@ -766,7 +800,7 @@ class BLE_Bluez_Client:
                 # Remove GATT data
                 dbus.service.Object.remove_from_connection(gatt_app_obj)
 
-                GLib.timeout_add_seconds(2, self.verify_blecent_disconnect)
+                GLib.timeout_add_seconds(5, self.verify_blecent_disconnect)
                 event_loop.run()
 
                 if ADV_STOP:
@@ -784,9 +818,10 @@ class BLE_Bluez_Client:
                 if DISCOVERY_START:
                     self.adapter.StopDiscovery()
                     DISCOVERY_START = False
+            time.sleep(15)
 
-            # Power off Adapter
-            self.props_iface_obj.Set(ADAPTER_IFACE, "Powered", dbus.Boolean(0))
+            SIGNAL_CAUGHT = False
+            GLib.timeout_add_seconds(5, verify_signal_is_caught)
             event_loop.run()
 
             if not DEVICE_CONNECTED:
@@ -794,12 +829,6 @@ class BLE_Bluez_Client:
             else:
                 print("Warning: device could not be disconnected")
 
-            print("powering off adapter...")
-            if not ADAPTER_ON:
-                print("bluetooth adapter powered off")
-            else:
-                print("\nWarning: Bluetooth adapter not powered off")
-
-        except Exception as e:
-            print(e)
+        except Exception:
+            print(traceback.format_exc())
             return False