code: def _on_connection_failed(self, connection_id, adapter_id, success, failure_reason):
          
          self._logger.info("_on_connection_failed connection_id=%d, reason=%s", connection_id, failure_reason)
  
          try:
              context = self.connections.get_context(connection_id)
          except ArgumentError:
              self._logger.info("Unable to obtain connection data on unknown connection %d", connection_id)
              context = {}
  
          # Cancel the connection to be able to resend a connect request later (else the controller sends an error)
          self.bable.cancel_connection(sync=False)
  
          if context.get('retry_connect') and context.get('retries') > 0:
              context['retries'] -= 1
              self.connect_async(
                  connection_id,
                  context['connection_string'],
                  context['callback'],
                  context['retries'],
                  context
              )
          else:
              self.connections.finish_connection(
                  connection_id,
                  False,
                  context.get('failure_reason', failure_reason)
              )
docs: Callback function called when a connection has failed.
          It is executed in the baBLE working thread: should not be blocking.
  
          Args:
              connection_id (int): A unique identifier for this connection on the DeviceManager that owns this adapter.
              adapter_id (int): A unique identifier for the DeviceManager
              success (bool): A bool indicating that the operation is successful or not
              failure_reason (any): An object indicating the reason why the operation is not successful (else None)