Skip to content

Commit b1fe487

Browse files
niag-Oticoncarlescufi
authored andcommitted
Bluetooth: controller: Release of padding PDUs for framed production
Implemented: -- Released framed padding PDUs when data received in SDUs for a given event do not fully utilise BN. Signed-off-by: Nirosharn Amarasinghe <[email protected]>
1 parent 5879d2d commit b1fe487

File tree

1 file changed

+65
-12
lines changed
  • subsys/bluetooth/controller/ll_sw

1 file changed

+65
-12
lines changed

subsys/bluetooth/controller/ll_sw/isoal.c

Lines changed: 65 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -250,14 +250,14 @@ isoal_status_t isoal_sink_create(
250250
*/
251251
if (role == BT_CONN_ROLE_PERIPHERAL) {
252252
isoal_global.sink_state[*hdl].session.latency_unframed =
253-
stream_sync_delay + ((flush_timeout - 1) * iso_interval_us);
253+
stream_sync_delay + ((flush_timeout - 1UL) * iso_interval_us);
254254

255255
isoal_global.sink_state[*hdl].session.latency_framed =
256256
stream_sync_delay + sdu_interval + (flush_timeout * iso_interval_us);
257257
} else if (role == BT_CONN_ROLE_CENTRAL) {
258258
isoal_global.sink_state[*hdl].session.latency_unframed =
259259
stream_sync_delay - group_sync_delay -
260-
(((iso_interval_us / sdu_interval) - 1) * iso_interval_us);
260+
(((iso_interval_us / sdu_interval) - 1UL) * iso_interval_us);
261261

262262
isoal_global.sink_state[*hdl].session.latency_framed =
263263
stream_sync_delay - group_sync_delay;
@@ -921,7 +921,7 @@ static isoal_status_t isoal_rx_framed_consume(struct isoal_sink *sink,
921921
seq_err = (meta->payload_number != (sp->prev_pdu_id + 1));
922922
}
923923

924-
end_of_pdu = ((uint8_t *) pdu_meta->pdu->payload) + pdu_meta->pdu->len - 1;
924+
end_of_pdu = ((uint8_t *) pdu_meta->pdu->payload) + pdu_meta->pdu->len - 1UL;
925925
seg_hdr = (pdu_err || seq_err || pdu_padding) ? NULL :
926926
(struct pdu_iso_sdu_sh *) pdu_meta->pdu->payload;
927927

@@ -1064,7 +1064,7 @@ static isoal_status_t isoal_rx_framed_consume(struct isoal_sink *sink,
10641064
if (((uint8_t *) seg_hdr) > end_of_pdu) {
10651065
seg_hdr = NULL;
10661066
} else if (isoal_check_seg_header(seg_hdr,
1067-
(uint8_t)(end_of_pdu + 1 - ((uint8_t *) seg_hdr))) ==
1067+
(uint8_t)(end_of_pdu + 1UL - ((uint8_t *) seg_hdr))) ==
10681068
ISOAL_SDU_STATUS_LOST_DATA) {
10691069
seg_err = true;
10701070
seg_hdr = NULL;
@@ -1457,10 +1457,17 @@ static isoal_status_t isoal_tx_pdu_emit(const struct isoal_source *source_ctx,
14571457
return status;
14581458
}
14591459

1460-
/* Allocates a new PDU only if the previous PDU was emitted */
1460+
/**
1461+
* Allocates a new PDU only if the previous PDU was emitted
1462+
* @param[in] source ISO-AL source reference
1463+
* @param[in] tx_sdu SDU fragment to be transmitted (can be NULL)
1464+
* @return Error status of operation
1465+
*/
14611466
static isoal_status_t isoal_tx_allocate_pdu(struct isoal_source *source,
14621467
const struct isoal_sdu_tx *tx_sdu)
14631468
{
1469+
ARG_UNUSED(tx_sdu);
1470+
14641471
struct isoal_source_session *session;
14651472
struct isoal_pdu_production *pp;
14661473
struct isoal_pdu_produced *pdu;
@@ -2050,16 +2057,15 @@ static isoal_status_t isoal_tx_framed_produce(struct isoal_source *source,
20502057

20512058
err |= err_emit;
20522059

2053-
/* TODO: Send padding PDU(s) if required
2054-
*
2055-
* BT Core V5.3 : Vol 6 Low Energy Controller : Part G IS0-AL:
2060+
/* BT Core V5.3 : Vol 6 Low Energy Controller : Part G IS0-AL:
20562061
* 2 ISOAL Features :
20572062
* Padding is required when the data does not add up to the
20582063
* configured number of PDUs that are specified in the BN
20592064
* parameter per CIS or BIS event.
20602065
*
20612066
* When padding PDUs as opposed to null PDUs are required for
2062-
* framed production is not clear.
2067+
* framed production is not clear. Padding PDUs will be released
2068+
* on the next event prepare trigger.
20632069
*/
20642070
padding_pdu = false;
20652071
zero_length_sdu = false;
@@ -2080,25 +2086,72 @@ static isoal_status_t isoal_tx_framed_event_prepare_handle(isoal_source_handle_t
20802086
{
20812087
struct isoal_source_session *session;
20822088
struct isoal_pdu_production *pp;
2089+
uint64_t first_event_payload;
20832090
struct isoal_source *source;
20842091
uint64_t last_event_payload;
2092+
isoal_status_t err_alloc;
2093+
bool release_padding;
20852094
isoal_status_t err;
20862095

20872096
err = ISOAL_STATUS_OK;
2097+
err_alloc = ISOAL_STATUS_OK;
2098+
release_padding = false;
20882099

20892100
source = &isoal_global.source_state[source_hdl];
20902101
session = &source->session;
20912102
pp = &source->pdu_production;
2092-
last_event_payload = (session->burst_number * (event_count + 1)) - 1;
2103+
first_event_payload = (session->burst_number * event_count);
2104+
last_event_payload = (session->burst_number * (event_count + 1ULL)) - 1ULL;
20932105

20942106
if (pp->pdu_available > 0 &&
20952107
pp->payload_number <= last_event_payload) {
20962108
/* Pending PDU that should be released for framed TX */
20972109
err = isoal_tx_try_emit_pdu(source, true, PDU_BIS_LLID_FRAMED);
20982110
}
20992111

2100-
if (pp->payload_number < last_event_payload + 1) {
2101-
pp->payload_number = last_event_payload + 1;
2112+
if (pp->mode != ISOAL_PRODUCTION_MODE_DISABLED) {
2113+
/* BT Core V5.3 : Vol 6 Low Energy Controller :
2114+
* Part G IS0-AL:
2115+
*
2116+
* 2 ISOAL Features :
2117+
* Padding is required when the data does not add up to the
2118+
* configured number of PDUs that are specified in the BN
2119+
* parameter per CIS or BIS event.
2120+
*
2121+
* There is some lack of clarity in the specifications as to why
2122+
* padding PDUs should be used as opposed to null PDUs. However
2123+
* if a payload is not available, the LL must default to waiting
2124+
* for the flush timeout before it can proceed to the next
2125+
* payload.
2126+
*
2127+
* This means a loss of retransmission capacity for future
2128+
* payloads that could exist. Sending padding PDUs will prevent
2129+
* this loss while not resulting in additional SDUs on the
2130+
* receiver. However it does incur the allocation and handling
2131+
* overhead on the transmitter.
2132+
*
2133+
* As an interpretation of the specification, padding PDUs will
2134+
* only be released if an SDU has been received in the current
2135+
* event.
2136+
*/
2137+
if (pp->payload_number > first_event_payload) {
2138+
release_padding = true;
2139+
}
2140+
}
2141+
2142+
if (release_padding) {
2143+
while (!err && !err_alloc && (pp->payload_number < last_event_payload + 1ULL)) {
2144+
err_alloc = isoal_tx_allocate_pdu(source, NULL);
2145+
2146+
err = isoal_tx_try_emit_pdu(source, true, PDU_BIS_LLID_FRAMED);
2147+
}
2148+
}
2149+
2150+
/* Not possible to recover if allocation or emit fails here*/
2151+
LL_ASSERT(!(err || err_alloc));
2152+
2153+
if (pp->payload_number < last_event_payload + 1ULL) {
2154+
pp->payload_number = last_event_payload + 1ULL;
21022155
}
21032156

21042157
return err;

0 commit comments

Comments
 (0)