Skip to content
6 changes: 2 additions & 4 deletions nimble/controller/src/ble_ll_adv.c
Original file line number Diff line number Diff line change
Expand Up @@ -3461,10 +3461,8 @@ ble_ll_adv_ext_set_param(const uint8_t *cmdbuf, uint8_t len,
}
#endif

adv_itvl_min = cmd->pri_itvl_min[2] << 16 | cmd->pri_itvl_min[1] << 8 |
cmd->pri_itvl_min[0];
adv_itvl_max = cmd->pri_itvl_max[2] << 16 | cmd->pri_itvl_max[1] << 8 |
cmd->pri_itvl_max[0];
adv_itvl_min = get_le24(cmd->pri_itvl_min);
adv_itvl_max = get_le24(cmd->pri_itvl_max);

if (props & ~BLE_HCI_LE_SET_EXT_ADV_PROP_MASK) {
rc = BLE_ERR_INV_HCI_CMD_PARMS;
Expand Down
10 changes: 10 additions & 0 deletions nimble/controller/src/ble_ll_ctrl.c
Original file line number Diff line number Diff line change
Expand Up @@ -650,6 +650,11 @@ ble_ll_ctrl_phy_from_phy_mask(uint8_t phy_mask)
{
uint8_t phy;

/* One and only one bit shall be set */
if (__builtin_popcount(phy_mask) != 1) {
return 0;
}

/*
* NOTE: wipe out unsupported PHYs. There should not be an unsupported
* in this mask if the other side is working correctly.
Expand Down Expand Up @@ -3224,6 +3229,11 @@ ble_ll_ctrl_tx_done(struct os_mbuf *txpdu, struct ble_ll_conn_sm *connsm)
connsm->flags.pending_encrypt_restart = 1;
}
break;
#else
case BLE_LL_CTRL_PAUSE_ENC_RSP:
BLE_LL_ASSERT(connsm->conn_role == BLE_LL_CONN_ROLE_CENTRAL);
connsm->flags.pending_encrypt_restart = 1;
break;
#endif
#endif
#if MYNEWT_VAL(BLE_LL_PHY)
Expand Down
4 changes: 4 additions & 0 deletions nimble/controller/src/ble_ll_hci_supp_cmd.c
Original file line number Diff line number Diff line change
Expand Up @@ -273,6 +273,10 @@ static const uint8_t octet_43 = OCTET(
#if MYNEWT_VAL(BLE_LL_CFG_FEAT_LL_SCA_UPDATE)
BIT(2) /* HCI LE Request Peer SCA */
#endif
#if MYNEWT_VAL(BLE_LL_ISO)
BIT(3) /* HCI LE Setup ISO Data Path */
BIT(4) /* HCI LE Remove ISO Data Path */
#endif
);

static const uint8_t octet_44 = OCTET(
Expand Down
128 changes: 86 additions & 42 deletions nimble/controller/src/ble_ll_iso_big.c
Original file line number Diff line number Diff line change
Expand Up @@ -84,7 +84,7 @@ struct big_params {
uint8_t pto; /* 0-15, mandatory 0 */
uint32_t sdu_interval;
uint16_t iso_interval;
uint16_t max_transport_latency;
uint16_t max_transport_latency_ms;
uint16_t max_sdu;
uint8_t max_pdu;
uint8_t phy;
Expand Down Expand Up @@ -132,6 +132,7 @@ struct ble_ll_iso_big {
uint64_t bis_counter;

uint32_t sync_delay;
uint32_t transport_latency_us;
uint32_t event_start;
uint8_t event_start_us;
uint32_t anchor_base_ticks;
Expand Down Expand Up @@ -325,7 +326,7 @@ ble_ll_iso_big_biginfo_copy(struct ble_ll_iso_big *big, uint8_t *dptr,
*/
if (event_start <= base_ticks) {
ble_ll_tmr_add(&event_start, &event_start_us, big->iso_interval * 1250);
counter++;
counter += big->bn;
}

/* Drop BIGInfo if BIG event is still before AUX_SYNC_IND. This should not
Expand Down Expand Up @@ -439,13 +440,17 @@ ble_ll_iso_big_chan_map_update_complete(struct ble_ll_iso_big *big)
}

static void
ble_ll_iso_big_update_event_start(struct ble_ll_iso_big *big)
ble_ll_iso_big_update_event_start(struct ble_ll_iso_big *big,
uint64_t new_big_counter)
{
os_sr_t sr;

OS_ENTER_CRITICAL(sr);
/* This has to be updated atomically to avoid races when copying to BIGInfo */
big->event_start = big->sch.start_time + g_ble_ll_sched_offset_ticks;
big->event_start_us = big->sch.remainder;
big->bis_counter += (new_big_counter - big->big_counter) * big->bn;
big->big_counter = new_big_counter;
OS_EXIT_CRITICAL(sr);
}

Expand All @@ -461,6 +466,7 @@ ble_ll_iso_big_event_done(struct ble_ll_iso_big *big)
uint16_t exp;
uint32_t now;
#endif
uint64_t big_counter;
struct ble_hci_ev_num_comp_pkts *hci_ev_ncp = NULL;
int num_completed_pkt;
int idx;
Expand Down Expand Up @@ -547,13 +553,13 @@ ble_ll_iso_big_event_done(struct ble_ll_iso_big *big)

big->sch.start_time = big->event_start;
big->sch.remainder = big->event_start_us;
big_counter = big->big_counter;

do {
big->big_counter++;
big->bis_counter += big->bn;
big_counter++;

if (big->control_active &&
(big->control_instant == (uint16_t)big->big_counter)) {
(big->control_instant == (uint16_t)big_counter)) {
switch (big->control_active) {
case BIG_CONTROL_ACTIVE_TERM:
ble_ll_iso_big_terminate_complete(big);
Expand Down Expand Up @@ -582,7 +588,7 @@ ble_ll_iso_big_event_done(struct ble_ll_iso_big *big)
}

if (big->control_active) {
big->control_instant = big->big_counter + 6;
big->control_instant = big_counter + 6;
big->cstf = 1;
big->cssn += 1;
}
Expand All @@ -596,7 +602,7 @@ ble_ll_iso_big_event_done(struct ble_ll_iso_big *big)
assert(rc == 0);
} while (rc < 0);

ble_ll_iso_big_update_event_start(big);
ble_ll_iso_big_update_event_start(big, big_counter);
}

static void
Expand Down Expand Up @@ -986,12 +992,16 @@ ble_ll_iso_big_create(uint8_t big_handle, uint8_t adv_handle, uint8_t num_bis,

BLE_LL_ASSERT(big);

big_pool_free--;

advsm = ble_ll_adv_sync_get(adv_handle);
if (!advsm) {
ble_ll_iso_big_free(big);
return -ENOENT;
}

if (ble_ll_adv_sync_big_add(advsm, big) < 0) {
ble_ll_iso_big_free(big);
return -ENOENT;
}

Expand Down Expand Up @@ -1044,34 +1054,8 @@ ble_ll_iso_big_create(uint8_t big_handle, uint8_t adv_handle, uint8_t num_bis,
bp->sdu_interval, bp->bn, pte);
}

big_pool_free--;
bis_pool_free -= num_bis;

/* Calculate AA for each BIS and BIG Control. We have to repeat this process
* until all AAs are valid.
*/
do {
rc = 0;

seed_aa = ble_ll_utils_calc_seed_aa();
big->ctrl_aa = ble_ll_utils_calc_big_aa(seed_aa, 0);

if (!ble_ll_utils_verify_aa(big->ctrl_aa)) {
continue;
}

rc = 1;

STAILQ_FOREACH(bis, &big->bis_q, bis_q_next) {
bis->aa = ble_ll_utils_calc_big_aa(seed_aa, bis->num);
if (!ble_ll_utils_verify_aa(bis->aa)) {
rc = 0;
break;
}
bis->chan_id = bis->aa ^ (bis->aa >> 16);
}
} while (rc == 0);

big->bn = bp->bn;
big->pto = bp->pto;
big->irc = bp->irc;
Expand Down Expand Up @@ -1107,13 +1091,54 @@ ble_ll_iso_big_create(uint8_t big_handle, uint8_t adv_handle, uint8_t num_bis,
big->pto = 0;
}

/* Core 6.0, Vol 6, Part G, 3.2.1 and 3.2.2 */
if (big->framed) {
big->transport_latency_us = big->sync_delay +
(big->pto * (big->nse / big->bn - big->irc) + 1) *
big->iso_interval * 1250 + big->sdu_interval;
} else {
big->transport_latency_us = big->sync_delay +
(big->pto * (big->nse / big->bn - big->irc) + 1) *
big->iso_interval * 1250 - big->sdu_interval;
}

if (big->transport_latency_us > bp->max_transport_latency_ms * 1000) {
ble_ll_iso_big_free(big);
return -ERANGE;
}

/* Calculate AA for each BIS and BIG Control. We have to repeat this process
* until all AAs are valid.
*/
do {
rc = 0;

seed_aa = ble_ll_utils_calc_seed_aa();
big->ctrl_aa = ble_ll_utils_calc_big_aa(seed_aa, 0);

if (!ble_ll_utils_verify_aa(big->ctrl_aa)) {
continue;
}

rc = 1;

STAILQ_FOREACH(bis, &big->bis_q, bis_q_next) {
bis->aa = ble_ll_utils_calc_big_aa(seed_aa, bis->num);
if (!ble_ll_utils_verify_aa(bis->aa)) {
rc = 0;
break;
}
bis->chan_id = bis->aa ^ (bis->aa >> 16);
}
} while (rc == 0);

ble_ll_iso_big_biginfo_calc(big, seed_aa);

if (big->encrypted) {
ble_ll_iso_big_calculate_gsk(big, bp->broadcast_code);
ble_ll_iso_big_calculate_iv(big);
}

ble_ll_iso_big_biginfo_calc(big, seed_aa);

/* For now we will schedule complete event as single item. This allows for
* shortest possible subevent space (150us) but can create sequence of long
* events that will block scheduler from other activities. To mitigate this
Expand Down Expand Up @@ -1160,7 +1185,7 @@ ble_ll_iso_big_create(uint8_t big_handle, uint8_t adv_handle, uint8_t num_bis,
}
} while (rc < 0);

ble_ll_iso_big_update_event_start(big);
ble_ll_iso_big_update_event_start(big, big->big_counter);

big_pending = big;

Expand Down Expand Up @@ -1253,10 +1278,7 @@ ble_ll_iso_big_hci_evt_complete(void)
evt->big_handle = big->handle;
put_le24(evt->big_sync_delay, big->sync_delay);
/* Core 5.3, Vol 6, Part G, 3.2.2 */
put_le24(evt->transport_latency_big,
big->sync_delay +
(big->pto * (big->nse / big->bn - big->irc) + 1) * big->iso_interval * 1250 -
big->sdu_interval);
put_le24(evt->transport_latency_big, big->transport_latency_us);
evt->phy = big->phy;
evt->nse = big->nse;
evt->bn = big->bn;
Expand All @@ -1280,6 +1302,7 @@ ble_ll_iso_big_hci_create(const uint8_t *cmdbuf, uint8_t len)
{
const struct ble_hci_le_create_big_cp *cmd = (void *)cmdbuf;
struct big_params bp;
uint8_t valid_phys;
int rc;

if (len != sizeof(*cmd)) {
Expand All @@ -1297,8 +1320,20 @@ ble_ll_iso_big_hci_create(const uint8_t *cmdbuf, uint8_t len)
return BLE_ERR_INV_HCI_CMD_PARMS;
}

valid_phys = BLE_HCI_LE_PHY_1M_PREF_MASK;
#if MYNEWT_VAL(BLE_LL_CFG_FEAT_LE_2M_PHY)
valid_phys |= BLE_HCI_LE_PHY_2M_PREF_MASK;
#endif
#if MYNEWT_VAL(BLE_LL_CFG_FEAT_LE_CODED_PHY)
valid_phys |= BLE_HCI_LE_PHY_CODED_PREF_MASK;
#endif

if (cmd->phy & ~valid_phys) {
return BLE_ERR_UNSUPPORTED;
}

bp.sdu_interval = get_le24(cmd->sdu_interval);
bp.max_transport_latency = le16toh(cmd->max_transport_latency);
bp.max_transport_latency_ms = le16toh(cmd->max_transport_latency);
bp.max_sdu = le16toh(cmd->max_sdu);
if (cmd->phy & BLE_HCI_LE_PHY_2M_PREF_MASK) {
bp.phy = BLE_PHY_2M;
Expand Down Expand Up @@ -1327,12 +1362,16 @@ ble_ll_iso_big_hci_create(const uint8_t *cmdbuf, uint8_t len)
switch (rc) {
case 0:
break;
case -EALREADY:
return BLE_ERR_CMD_DISALLOWED;
case -EINVAL:
return BLE_ERR_INV_HCI_CMD_PARMS;
case -ENOMEM:
return BLE_ERR_CONN_REJ_RESOURCES;
case -ENOENT:
return BLE_ERR_UNK_ADV_INDENT;
case -ERANGE:
return BLE_ERR_UNSUPPORTED;
default:
return BLE_ERR_UNSPECIFIED;
}
Expand Down Expand Up @@ -1375,6 +1414,7 @@ ble_ll_iso_big_hci_create_test(const uint8_t *cmdbuf, uint8_t len)
bp.pto = cmd->pto;
bp.sdu_interval = get_le24(cmd->sdu_interval);
bp.iso_interval = le16toh(cmd->iso_interval);
bp.max_transport_latency_ms = 0x0fa0; /* max_transport_latency for HCI LE Create BIG */
bp.max_sdu = le16toh(cmd->max_sdu);
bp.max_pdu = le16toh(cmd->max_pdu);
/* TODO verify phy */
Expand Down Expand Up @@ -1413,12 +1453,16 @@ ble_ll_iso_big_hci_create_test(const uint8_t *cmdbuf, uint8_t len)
switch (rc) {
case 0:
break;
case -EALREADY:
return BLE_ERR_CMD_DISALLOWED;
case -EINVAL:
return BLE_ERR_INV_HCI_CMD_PARMS;
case -ENOMEM:
return BLE_ERR_CONN_REJ_RESOURCES;
case -ENOENT:
return BLE_ERR_UNK_ADV_INDENT;
case -ERANGE:
return BLE_ERR_UNSUPPORTED;
default:
return BLE_ERR_UNSPECIFIED;
}
Expand Down
Loading