Commit 7c6cf9aa authored by Vinayak Kariappa Chettimada's avatar Vinayak Kariappa Chettimada Committed by Carles Cufi
Browse files

Bluetooth: controller: BIG Sync terminate procedure



Implementation of BIG Sync terminate procedure.

Signed-off-by: default avatarVinayak Kariappa Chettimada <vich@nordicsemi.no>
parent 03a303ab
Loading
Loading
Loading
Loading
+1 −0
Original line number Diff line number Diff line
@@ -396,6 +396,7 @@ enum {
#if defined(CONFIG_BT_CTLR_SYNC_ISO)
	EVENT_DONE_EXTRA_TYPE_SYNC_ISO_ESTAB,
	EVENT_DONE_EXTRA_TYPE_SYNC_ISO,
	EVENT_DONE_EXTRA_TYPE_SYNC_ISO_TERMINATE,
#endif /* CONFIG_BT_CTLR_SYNC_ISO */
#endif /* CONFIG_BT_CTLR_SYNC_PERIODIC */
#endif /* CONFIG_BT_CTLR_ADV_EXT */
+6 −0
Original line number Diff line number Diff line
@@ -16,6 +16,9 @@ struct lll_sync_iso {
	uint16_t data_chan_remap_idx;

	uint64_t payload_count:39;
	uint64_t ctrl:1;
	uint64_t cssn_curr:3;
	uint64_t cssn_next:3;

	uint8_t data_chan_map[5];
	uint8_t data_chan_count:6;
@@ -40,7 +43,10 @@ struct lll_sync_iso {
	uint8_t bn_curr:3;
	uint8_t bis_curr:5;

	uint8_t term_reason;

	uint8_t ctrl_chan_use;
	uint16_t ctrl_instant;

	struct node_rx_pdu *payload[PDU_BIG_PAYLOAD_COUNT_MAX];
	uint8_t payload_count_max;
+63 −8
Original line number Diff line number Diff line
@@ -216,6 +216,9 @@ static int prepare_cb_common(struct lll_prepare_param *p)
	lll->irc_curr = 1U;
	lll->bn_curr = 1U;

	/* Initialize control subevent flag */
	lll->ctrl = 0U;

	/* Initialize trx chain count */
	trx_cnt = 0U;

@@ -407,15 +410,54 @@ static void isr_rx(void *param)

	/* Check CRC and generate ISO Data PDU */
	if (crc_ok) {
		struct pdu_bis *pdu;

		if ((lll->bn_curr == lll->bn) &&
		    (lll->irc_curr == lll->irc) &&
		    (lll->ptc_curr == lll->ptc) &&
		    (lll->bis_curr == lll->num_bis) &&
		    lll->ctrl) {
			lll->cssn_curr = lll->cssn_next;

			node_rx = ull_pdu_rx_alloc_peek(1);
			LL_ASSERT(node_rx);

			pdu = (void *)node_rx->pdu;
			if (pdu->ll_id != PDU_BIS_LLID_CTRL) {
				goto isr_rx_done;
			}

			if (pdu->ctrl.opcode == PDU_BIG_CTRL_TYPE_TERM_IND) {
				if (!lll->term_reason) {
					struct pdu_big_ctrl_term_ind *term;

					term = (void *)&pdu->ctrl.term_ind;
					lll->term_reason = term->reason;
					lll->ctrl_instant = term->instant;
				}
			}
		} else {
			node_rx = ull_pdu_rx_alloc_peek(3);
			if (!node_rx) {
				goto isr_rx_done;
			}
		}

		pdu = (void *)node_rx->pdu;

		/* Check for new control PDU in control subevent */
		if (pdu->cstf && (pdu->cssn != lll->cssn_curr)) {
			lll->cssn_next = pdu->cssn;
			/* TODO: check same CSSN is used in every subevent */
		}

		payload_index = lll->payload_tail + (lll->bn_curr - 1) +
				(lll->ptc_curr * lll->pto);
		if (payload_index >= lll->payload_count_max) {
			payload_index -= lll->payload_count_max;
		}

		node_rx = ull_pdu_rx_alloc_peek(3);

		if (node_rx && !lll->payload[payload_index] &&
		if (!lll->payload[payload_index] &&
		    ((payload_index >= lll->payload_tail) ||
		     (payload_index < lll->payload_head))) {
			struct node_rx_ftr *ftr;
@@ -486,7 +528,9 @@ isr_rx_find_subevent:
				skipped++;
				is_new_burst = 1U;

				/* Receive the missing (bn_curr)th Rx PDU of bis_curr */
				/* Receive the missing (bn_curr)th Rx PDU of
				 * bis_curr
				 */
				goto isr_rx_find_subevent;
			}
		} else {
@@ -517,10 +561,14 @@ isr_rx_find_subevent:
		goto isr_rx_next_subevent;
	}

	if (0) {
		/* Reeive the control PDU and close the BIG event
	if (!lll->ctrl && (lll->cssn_next != lll->cssn_curr)) {
		/* Receive the control PDU and close the BIG event
		 *  there after.
		 */
		lll->ctrl = 1U;

		/* control subevent to use bis = 0 and se_n = 1 */
		bis = 0U;

		goto isr_rx_next_subevent;
	}
@@ -548,10 +596,18 @@ isr_rx_find_subevent:
	}
#endif /* CONFIG_BT_CTLR_LOW_LAT_ULL */

	/* Calculate and place the drift information in done event */
	e = ull_event_done_extra_get();
	LL_ASSERT(e);

	/* Check if BIG terminate procedure received */
	if (lll->term_reason) {
		e->type = EVENT_DONE_EXTRA_TYPE_SYNC_ISO_TERMINATE;

		lll_isr_cleanup(param);
		return;
	}

	/* Calculate and place the drift information in done event */
	e->type = EVENT_DONE_EXTRA_TYPE_SYNC_ISO;
	e->trx_cnt = trx_cnt;
	e->crc_valid = crc_ok;
@@ -569,7 +625,6 @@ isr_rx_find_subevent:
	}

	lll_isr_cleanup(param);

	return;

isr_rx_next_subevent:
+4 −0
Original line number Diff line number Diff line
@@ -2724,6 +2724,10 @@ static inline void rx_demux_event_done(memq_link_t *link,
	case EVENT_DONE_EXTRA_TYPE_SYNC_ISO:
		ull_sync_iso_done(done);
		break;

	case EVENT_DONE_EXTRA_TYPE_SYNC_ISO_TERMINATE:
		ull_sync_iso_done_terminate(done);
		break;
#endif /* CONFIG_BT_CTLR_SYNC_ISO */
#endif /* CONFIG_BT_CTLR_SYNC_PERIODIC */
#endif /* CONFIG_BT_OBSERVER */
+43 −8
Original line number Diff line number Diff line
@@ -524,6 +524,34 @@ void ull_sync_iso_done(struct node_rx_event_done *done)
	}
}

void ull_sync_iso_done_terminate(struct node_rx_event_done *done)
{
	struct ll_sync_iso_set *sync_iso;
	struct lll_sync_iso *lll;
	struct node_rx_pdu *rx;
	uint8_t handle;
	uint32_t ret;

	/* Get reference to ULL context */
	sync_iso = CONTAINER_OF(done->param, struct ll_sync_iso_set, ull);
	lll = &sync_iso->lll;

	/* Populate the Sync Lost which will be enqueued in disabled_cb */
	rx = (void *)&sync_iso->node_rx_lost;
	rx->hdr.handle = ull_sync_iso_handle_get(sync_iso);
	rx->hdr.type = NODE_RX_TYPE_SYNC_ISO_LOST;
	rx->hdr.rx_ftr.param = sync_iso;
	*((uint8_t *)rx->pdu) = lll->term_reason;

	/* Stop Sync ISO Ticker */
	handle = ull_sync_iso_handle_get(sync_iso);
	ret = ticker_stop(TICKER_INSTANCE_ID_CTLR, TICKER_USER_ID_ULL_HIGH,
			  (TICKER_ID_SCAN_SYNC_ISO_BASE + handle),
			  ticker_stop_op_cb, (void *)sync_iso);
	LL_ASSERT((ret == TICKER_STATUS_SUCCESS) ||
		  (ret == TICKER_STATUS_BUSY));
}

static int init_reset(void)
{
	/* Initialize sync pool. */
@@ -541,12 +569,19 @@ static inline struct ll_sync_iso_set *sync_iso_acquire(void)

static void timeout_cleanup(struct ll_sync_iso_set *sync_iso)
{
	uint16_t handle;
	struct node_rx_pdu *rx;
	uint8_t handle;
	uint32_t ret;

	handle = ull_sync_iso_handle_get(sync_iso);
	/* Populate the Sync Lost which will be enqueued in disabled_cb */
	rx = (void *)&sync_iso->node_rx_lost;
	rx->hdr.handle = ull_sync_iso_handle_get(sync_iso);
	rx->hdr.type = NODE_RX_TYPE_SYNC_ISO_LOST;
	rx->hdr.rx_ftr.param = sync_iso;
	*((uint8_t *)rx->pdu) = BT_HCI_ERR_CONN_TIMEOUT;

	/* Stop Periodic Sync Ticker */
	/* Stop Sync ISO Ticker */
	handle = ull_sync_iso_handle_get(sync_iso);
	ret = ticker_stop(TICKER_INSTANCE_ID_CTLR, TICKER_USER_ID_ULL_HIGH,
			  (TICKER_ID_SCAN_SYNC_ISO_BASE + handle),
			  ticker_stop_op_cb, (void *)sync_iso);
@@ -645,18 +680,18 @@ static void disabled_cb(void *param)
{
	struct ll_sync_iso_set *sync_iso;
	struct node_rx_pdu *rx;
	memq_link_t *link;

	/* Get reference to ULL context */
	sync_iso = HDR_LLL2ULL(param);

	/* Generate BIG sync lost */
	rx = (void *)&sync_iso->node_rx_lost;
	rx->hdr.handle = ull_sync_iso_handle_get(sync_iso);
	rx->hdr.type = NODE_RX_TYPE_SYNC_ISO_LOST;
	rx->hdr.rx_ftr.param = sync_iso;
	*((uint8_t *)rx->pdu) = BT_HCI_ERR_CONN_TIMEOUT;
	LL_ASSERT(rx->hdr.link);
	link = rx->hdr.link;
	rx->hdr.link = NULL;

	/* Enqueue the BIG sync lost towards ULL context */
	ll_rx_put(rx->hdr.link, rx);
	ll_rx_put(link, rx);
	ll_rx_sched();
}
Loading