Beware that this post is related to an SDK in maintenance mode
More Info: Consider nRF Connect SDK for new designs

How to reconnect when Disconnection appear : BLEHci.conn_failed_to_be_established [pc_ble_driver_py]

Hello, I am using the nordic nRF52840-DK with the package pc-ble-driver-py and the example heart_rate_collector.py.

My problem is that sometimes the Bluetooth connection can't connect to the device with this error : 

New connection, conn_handle: 0

Disconnected, conn_handle: 0, reason: BLEHci.conn_failed_to_be_established

I know that this error can sometimes occurred. But I would like to know how can I reconnect automatically just after this error ? 

Knowing that this error is problematic because it stop my python script lunched from a batch file.

Thanks in advance.

Gaetan

Parents
  • Hello,

    I have check but the disconnection is not because of the range. Indeed, the driver works most of the time. 

    Also I already check if the peripherals keep advertising and it doesn't seem to be related because they keep advertising.

    Concerning the python script, it doesn't crash when I disconnect, It crash when a random disconnect appear.

    My question is this one, how to reconnect to the device after a random disconnection in my script.

    Gaetan

  • Again, pc_ble_driver_py is not my strong side.

    gaetan14 said:
    how to reconnect to the device after a random disconnection in my scrip

    How do you connect in the first place? I assume that it is some API that you have already used to connect to your device? Perhaps you can share with me what your current script looks like?

    Best regards,

    Edvin

  • So you have this disconnected callback function:
    on_gap_evt_disconnected()

    Is that triggered when you fail to connect? If so, can you try to trigger a new connect from within this function, in addition to only printing  "Disconnected: {} {}"?

    BR,

    Edvin

  • Yes the function on_gap_evt_disconnected() is triggered when it disconnect but as you can see in the picture, a raise NordicSemiException appear and stop the code. Because of that exception the script stop and i can't try to reconnect.

    Do you have an idea to solve this ?

    BR,

    Gaetan

  • My service discovery doesn't look like that. I see that the latest version on github has the same implementation as you, though.

    FYI, mine looks like this:

        @NordicSemiErrorCheck(expected=BLEGattStatusCode.success)
        def service_discovery(self, conn_handle, uuid=None):
            vendor_services = []
            self.driver.ble_gattc_prim_srvc_disc(conn_handle, uuid, 0x0001)
    
            while True:
                response = self.evt_sync[conn_handle].wait(
                    evt=BLEEvtID.gattc_evt_prim_srvc_disc_rsp
                )
    
                if response["status"] == BLEGattStatusCode.success:
                    for s in response["services"]:
                        if s.uuid.value == BLEUUID.Standard.unknown:
                            vendor_services.append(s)
                        else:
                            self.db_conns[conn_handle].services.append(s)
                elif response["status"] == BLEGattStatusCode.attribute_not_found:
                    break
                else:
                    return response["status"]
    
                if response["services"][-1].end_handle == 0xFFFF:
                    break
                else:
                    self.driver.ble_gattc_prim_srvc_disc(
                        conn_handle, uuid, response["services"][-1].end_handle + 1
                    )
    
            for s in vendor_services:
                # Read service handle to obtain full 128-bit UUID.
                self.driver.ble_gattc_read(conn_handle, s.start_handle, 0)
                response = self.evt_sync[conn_handle].wait(evt=BLEEvtID.gattc_evt_read_rsp)
                if response["status"] != BLEGattStatusCode.success:
                    continue
    
                # Check response length.
                if len(response["data"]) != 16:
                    continue
    
                # Create UUIDBase object and register it in softdevice
                base = BLEUUIDBase(
                    response["data"][::-1], driver.BLE_UUID_TYPE_VENDOR_BEGIN
                )
                self.driver.ble_vs_uuid_add(base)
    
                # Rediscover this service.
                self.driver.ble_gattc_prim_srvc_disc(conn_handle, uuid, s.start_handle)
                response = self.evt_sync[conn_handle].wait(
                    evt=BLEEvtID.gattc_evt_prim_srvc_disc_rsp
                )
                if response["status"] == BLEGattStatusCode.success:
                    # Assign UUIDBase manually
                    # See:
                    #  https://github.com/NordicSemiconductor/pc-ble-driver-py/issues/38
                    for s in response["services"]:
                        s.uuid.base = base
                    self.db_conns[conn_handle].services.extend(response["services"])
    
            for s in self.db_conns[conn_handle].services:
                self.driver.ble_gattc_char_disc(conn_handle, s.start_handle, s.end_handle)
                while True:
                    response = self.evt_sync[conn_handle].wait(
                        evt=BLEEvtID.gattc_evt_char_disc_rsp
                    )
                    if response["status"] == BLEGattStatusCode.success:
                        for char in response["characteristics"]:
                            s.char_add(char)
                    elif response["status"] == BLEGattStatusCode.attribute_not_found:
                        break
                    else:
                        return response["status"]
    
                    self.driver.ble_gattc_char_disc(
                        conn_handle,
                        response["characteristics"][-1].handle_decl + 1,
                        s.end_handle,
                    )
    
                for ch in s.chars:
                    self.driver.ble_gattc_desc_disc(
                        conn_handle, ch.handle_value, ch.end_handle
                    )
                    while True:
                        response = self.evt_sync[conn_handle].wait(
                            evt=BLEEvtID.gattc_evt_desc_disc_rsp
                        )
                        if response["status"] == BLEGattStatusCode.success:
                            ch.descs.extend(response["descriptors"])
                        elif response["status"] == BLEGattStatusCode.attribute_not_found:
                            break
                        else:
                            return response["status"]
    
                        if response["descriptors"][-1].handle == ch.end_handle:
                            break
                        else:
                            self.driver.ble_gattc_desc_disc(
                                conn_handle,
                                response["descriptors"][-1].handle + 1,
                                ch.end_handle,
                            )
            return BLEGattStatusCode.success

    Either way, if you want to continue after the disconnection, you should remove the exception that is raised. There is no need to continue the service discovery if they are not connected. Instead, you should start scanning again after the disconnect.

    Best regards,

    Edvin

  • Yes it is exactly what i want to do ! I want to stop the service discovery after a disconnection and start scanning again after the disconnect. 

    But how can I do this because my code will continue to be execute ?

    Best regards,

    Gaetan

  • Did you try to remove the line that raises the exception?

    If not, please try this.

Reply Children
Related