Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 72d5fba8 authored by Jakub Pawlowski's avatar Jakub Pawlowski
Browse files

CTKD from LE to Classic stability fix

When bond is established using LE transport with CTKD, we would start a
500ms timer to check if other side reports any errors. If connection or
disconnection happens during that time on classic transport, we would
reset the SMP control block, and cancel this alarm.
Even if it were to fire, the state machine would go into idle state, and
we won't send some callbacks that are crucial to inform upper layers
that the pairing was indeed successfull.

After this patch, classic connection/disconnection doesn't impact the
SMP control block, and the timer always fires.

Bug: 246560805
Test: Bond using LE transport 10 times in a row with device supporting
      CTKD
Change-Id: Id97aa338a20163b1d571c48b4dba224c95ee4880
parent 34f101ab
Loading
Loading
Loading
Loading
+20 −2
Original line number Diff line number Diff line
@@ -24,6 +24,7 @@

#define LOG_TAG "bluetooth"

#include <base/logging.h>
#include <string.h>

#include "bt_target.h"
@@ -35,11 +36,10 @@
#include "osi/include/log.h"
#include "osi/include/osi.h"  // UNUSED_ATTR
#include "smp_int.h"
#include "stack/btm/btm_dev.h"
#include "stack/include/bt_hdr.h"
#include "types/raw_address.h"

#include <base/logging.h>

static void smp_connect_callback(uint16_t channel, const RawAddress& bd_addr,
                                 bool connected, uint16_t reason,
                                 tBT_TRANSPORT transport);
@@ -250,6 +250,24 @@ static void smp_br_connect_callback(uint16_t channel, const RawAddress& bd_addr,

  if (bd_addr != p_cb->pairing_bda) return;

  /* Check if we already finished SMP pairing over LE, and are waiting to
   * check if other side returns some errors. Connection/disconnection on
   * Classic transport shouldn't impact that.
   */
  tBTM_SEC_DEV_REC* p_dev_rec = btm_find_dev(p_cb->pairing_bda);
  if (smp_get_state() == SMP_STATE_BOND_PENDING &&
      (p_dev_rec && p_dev_rec->is_link_key_known()) &&
      alarm_is_scheduled(p_cb->delayed_auth_timer_ent)) {
    /* If we were to not return here, we would reset SMP control block, and
     * delayed_auth_timer_ent would never be executed. Even though we stored all
     * keys, stack would consider device as not bonded. It would reappear after
     * stack restart, when we re-read record from storage. Service discovery
     * would stay broken.
     */
    LOG_INFO("Classic event after CTKD on LE transport");
    return;
  }

  if (connected) {
    if (!p_cb->connect_initialized) {
      p_cb->connect_initialized = true;