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

Commit 6d783d0d authored by Etienne Ruffieux's avatar Etienne Ruffieux Committed by Automerger Merge Worker
Browse files

Merge "Handle conflicts in avct browse" into main am: c9e68ce5

parents 586516a1 c9e68ce5
Loading
Loading
Loading
Loading
+2 −1
Original line number Original line Diff line number Diff line
@@ -696,7 +696,8 @@ tAVCT_BCB* avct_bcb_by_lcid(uint16_t lcid) {
  int idx;
  int idx;


  for (idx = 0; idx < AVCT_NUM_LINKS; idx++, p_bcb++) {
  for (idx = 0; idx < AVCT_NUM_LINKS; idx++, p_bcb++) {
    if (p_bcb->allocated && (p_bcb->ch_lcid == lcid)) {
    if (p_bcb->allocated &&
        ((p_bcb->ch_lcid == lcid) || (p_bcb->conflict_lcid == lcid))) {
      return p_bcb;
      return p_bcb;
    }
    }
  }
  }
+1 −0
Original line number Original line Diff line number Diff line
@@ -92,6 +92,7 @@ typedef struct {
  uint8_t allocated;  /* 0, not allocated. index+1, otherwise. */
  uint8_t allocated;  /* 0, not allocated. index+1, otherwise. */
  uint8_t state;      /* The state machine state */
  uint8_t state;      /* The state machine state */
  uint8_t ch_state;   /* L2CAP channel state */
  uint8_t ch_state;   /* L2CAP channel state */
  uint16_t conflict_lcid; /* L2CAP channel LCID */
  BT_HDR* p_tx_msg; /* Message to be sent - in case the browsing channel is not
  BT_HDR* p_tx_msg; /* Message to be sent - in case the browsing channel is not
                       open when MsgReg is called */
                       open when MsgReg is called */
  uint8_t ch_close; /* CCB index+1, if CCB initiated channel close */
  uint8_t ch_close; /* CCB index+1, if CCB initiated channel close */
+74 −13
Original line number Original line Diff line number Diff line
@@ -64,6 +64,36 @@ const tL2CAP_APPL_INFO avct_l2c_br_appl = {avct_l2c_br_connect_ind_cback,
                                           NULL,
                                           NULL,
                                           NULL};
                                           NULL};


/*******************************************************************************
 *
 * Function         avct_l2c_br_is_passive
 *
 * Description      check is the CCB associated with the given BCB was created
 *                  as passive
 *
 * Returns          true, if the given CCB is created as AVCT_PASSIVE
 *
 ******************************************************************************/
static bool avct_l2c_br_is_passive(tAVCT_BCB* p_bcb) {
  bool is_passive = false;
  tAVCT_LCB* p_lcb;
  tAVCT_CCB* p_ccb = &avct_cb.ccb[0];
  p_lcb = avct_lcb_by_bcb(p_bcb);
  int i;

  for (i = 0; i < AVCT_NUM_CONN; i++, p_ccb++) {
    if (p_ccb->allocated && (p_ccb->p_lcb == p_lcb)) {
      AVCT_TRACE_DEBUG("Is bcb associated ccb control passive :0x%x",
                       p_ccb->cc.control);
      if (p_ccb->cc.control & AVCT_PASSIVE) {
        is_passive = true;
        break;
      }
    }
  }
  return is_passive;
}

/*******************************************************************************
/*******************************************************************************
 *
 *
 * Function         avct_l2c_br_connect_ind_cback
 * Function         avct_l2c_br_connect_ind_cback
@@ -94,6 +124,16 @@ void avct_l2c_br_connect_ind_cback(const RawAddress& bd_addr, uint16_t lcid,
      p_bcb->allocated = p_lcb->allocated; /* copy the index from lcb */
      p_bcb->allocated = p_lcb->allocated; /* copy the index from lcb */


      result = L2CAP_CONN_OK;
      result = L2CAP_CONN_OK;
    } else {
      if (!avct_l2c_br_is_passive(p_bcb) || (p_bcb->ch_state == AVCT_CH_OPEN)) {
        /* this BCB included CT role - reject */
        result = L2CAP_CONN_NO_RESOURCES;
      } else {
        /* add channel ID to conflict ID */
        p_bcb->conflict_lcid = p_bcb->ch_lcid;
        result = L2CAP_CONN_OK;
        AVCT_TRACE_DEBUG("Detected conflict_lcid:0x%x", p_bcb->conflict_lcid);
      }
    }
    }
  }
  }
  /* else no control channel yet, reject */
  /* else no control channel yet, reject */
@@ -103,6 +143,7 @@ void avct_l2c_br_connect_ind_cback(const RawAddress& bd_addr, uint16_t lcid,


  /* If we reject the connection, send DisconnectReq */
  /* If we reject the connection, send DisconnectReq */
  if (result != L2CAP_CONN_OK) {
  if (result != L2CAP_CONN_OK) {
    AVCT_TRACE_DEBUG("Connection rejected to lcid:0x%x", lcid);
    L2CA_DisconnectReq(lcid);
    L2CA_DisconnectReq(lcid);
  }
  }


@@ -117,11 +158,16 @@ void avct_l2c_br_connect_ind_cback(const RawAddress& bd_addr, uint16_t lcid,
}
}


void avct_br_on_l2cap_error(uint16_t lcid, uint16_t result) {
void avct_br_on_l2cap_error(uint16_t lcid, uint16_t result) {
  tAVCT_BCB* p_lcb = avct_bcb_by_lcid(lcid);
  tAVCT_BCB* p_bcb = avct_bcb_by_lcid(lcid);
  if (p_lcb == nullptr) return;
  if (p_bcb == nullptr) return;


  if (p_bcb->ch_state == AVCT_CH_CONN && p_bcb->conflict_lcid == lcid) {
    AVCT_TRACE_DEBUG("Reset conflict_lcid:0x%x", p_bcb->conflict_lcid);
    p_bcb->conflict_lcid = 0;
    return;
  }
  /* store result value */
  /* store result value */
  p_lcb->ch_result = result;
  p_bcb->ch_result = result;


  /* Send L2CAP disconnect req */
  /* Send L2CAP disconnect req */
  avct_l2c_br_disconnect(lcid, 0);
  avct_l2c_br_disconnect(lcid, 0);
@@ -138,20 +184,35 @@ void avct_br_on_l2cap_error(uint16_t lcid, uint16_t result) {
 *
 *
 ******************************************************************************/
 ******************************************************************************/
void avct_l2c_br_connect_cfm_cback(uint16_t lcid, uint16_t result) {
void avct_l2c_br_connect_cfm_cback(uint16_t lcid, uint16_t result) {
  tAVCT_BCB* p_lcb;
  tAVCT_BCB* p_bcb;


  /* look up lcb for this channel */
  /* look up bcb for this channel */
  p_lcb = avct_bcb_by_lcid(lcid);
  p_bcb = avct_bcb_by_lcid(lcid);
  if ((p_lcb == NULL) || (p_lcb->ch_state != AVCT_CH_CONN)) return;


  if (result != L2CAP_CONN_OK) {
  if (p_bcb == NULL) {
    LOG(ERROR) << __func__ << ": invoked with non OK status";
    return;
    return;
  }
  }

  /* if in correct state */
  /* result is successful */
  if (p_bcb->ch_state == AVCT_CH_CONN) {
    /* if result successful */
    if (result == L2CAP_CONN_OK) {
      /* set channel state */
      /* set channel state */
  p_lcb->ch_state = AVCT_CH_CFG;
      p_bcb->ch_state = AVCT_CH_CFG;
    }
    /* else failure */
    else {
      AVCT_TRACE_ERROR("Invoked with non OK status");
    }
  } else if (p_bcb->conflict_lcid == lcid) {
    /* we must be in AVCT_CH_CFG state for the ch_lcid channel */
    if (result == L2CAP_CONN_OK) {
      /* just in case the peer also accepts our connection - Send L2CAP
       * disconnect req */
      AVCT_TRACE_DEBUG("Disconnect conflict_lcid:0x%x", p_bcb->conflict_lcid);
      L2CA_DisconnectReq(lcid);
    }
    p_bcb->conflict_lcid = 0;
  }
}
}


/*******************************************************************************
/*******************************************************************************