Skip to content

Commit

Permalink
workon: Framed PDU
Browse files Browse the repository at this point in the history
  • Loading branch information
MariuszSkamra committed Jan 23, 2025
1 parent 4f30057 commit 3c9035a
Show file tree
Hide file tree
Showing 8 changed files with 1,125 additions and 99 deletions.
2 changes: 1 addition & 1 deletion nimble/controller/include/controller/ble_ll_iso.h
Original file line number Diff line number Diff line change
Expand Up @@ -74,7 +74,7 @@ int ble_ll_iso_pdu_get(struct ble_ll_iso_conn *conn, uint8_t idx, uint8_t *llid,

void ble_ll_iso_conn_init(struct ble_ll_iso_conn *conn, uint16_t conn_handle,
uint8_t max_pdu, uint32_t iso_interval_us,
uint32_t sdu_interval_us, uint8_t bn, uint8_t pte);
uint32_t sdu_interval_us, uint8_t bn, uint8_t pte, uint8_t framing);
void ble_ll_iso_conn_free(struct ble_ll_iso_conn *conn);

int ble_ll_iso_conn_event_start(struct ble_ll_iso_conn *conn, uint32_t timestamp);
Expand Down
45 changes: 29 additions & 16 deletions nimble/controller/include/controller/ble_ll_isoal.h
Original file line number Diff line number Diff line change
Expand Up @@ -20,31 +20,30 @@
#ifndef H_BLE_LL_ISOAL_
#define H_BLE_LL_ISOAL_

#include <os/os_mbuf.h>
#include <syscfg/syscfg.h>

#ifdef __cplusplus
extern "C" {
#endif

#if MYNEWT_VAL(BLE_LL_ISO)

#include <os/os_mbuf.h>

struct ble_ll_isoal_mux {
#if MYNEWT_VAL(BLE_LL_ISOAL_MUX_PREFILL)
uint8_t active;
#endif

/* Max PDU length */
uint8_t max_pdu;
/* Number of expected SDUs per ISO interval */
uint8_t sdu_per_interval;

/* Number of expected PDUs per SDU */
uint8_t pdu_per_sdu;
/* Number of SDUs required to fill complete BIG/CIG event (i.e. with pt) */
uint8_t sdu_per_event;
/* Number of SDUs available for current event */
uint8_t sdu_in_event;

/* Number of PDUs available for current event */
uint8_t pdu_in_event;
/* Number of expected PDUs per ISO interval */
uint8_t pdu_per_interval;
/* Number of PDUs required to fill complete BIG/CIG event (i.e. with pt) */
uint8_t pdu_per_event;

STAILQ_HEAD(, os_mbuf_pkthdr) sdu_q;
uint16_t sdu_q_len;
Expand All @@ -54,28 +53,42 @@ struct ble_ll_isoal_mux {
uint32_t event_tx_timestamp;
uint32_t last_tx_timestamp;
uint16_t last_tx_packet_seq_num;

/* The head SDU Segment is the Continuation of an SDU */
uint8_t sc : 1;
uint8_t framed : 1;
uint8_t framing_mode : 1;
};

#define BLE_LL_ISOAL_SEGHDR(sc, cmplt, len) \
((uint16_t)((sc) & 0x01) | (((cmplt) & 0x01) << 1) | ((len) & 0xff) << 8)

#define BLE_LL_ISOAL_SEGHDR_SC(word) ((word) & 0x01)
#define BLE_LL_ISOAL_SEGHDR_CMPLT(word) ((word >> 1) & 0x01)
#define BLE_LL_ISOAL_SEGHDR_LEN(word) ((word >> 8) & 0xff)

#define BLE_LL_ISOAL_MUX_IS_FRAMED(framing) \
((framing) == BLE_HCI_ISO_FRAMING_FRAMED_SEGMENTABLE || \
(framing) == BLE_HCI_ISO_FRAMING_FRAMED_UNSEGMENTED)

void ble_ll_isoal_mux_init(struct ble_ll_isoal_mux *mux, uint8_t max_pdu,
uint32_t iso_interval_us, uint32_t sdu_interval_us,
uint8_t bn, uint8_t pte);
uint8_t bn, uint8_t pte, bool framed, bool framing_mode);
void ble_ll_isoal_mux_free(struct ble_ll_isoal_mux *mux);

int ble_ll_isoal_mux_event_start(struct ble_ll_isoal_mux *mux,
uint32_t timestamp);
void ble_ll_isoal_mux_event_start(struct ble_ll_isoal_mux *mux,
uint32_t timestamp);
int ble_ll_isoal_mux_event_done(struct ble_ll_isoal_mux *mux);

int ble_ll_isoal_mux_pdu_get(struct ble_ll_isoal_mux *mux, uint8_t idx,
uint8_t *llid, void *dptr);

void ble_ll_isoal_mux_sdu_enqueue(struct ble_ll_isoal_mux *mux,
struct os_mbuf *om, uint32_t timestamp);
struct os_mbuf *om);

void ble_ll_isoal_init(void);
void ble_ll_isoal_reset(void);

#endif /* BLE_LL_ISO */

#ifdef __cplusplus
}
#endif
Expand Down
37 changes: 24 additions & 13 deletions nimble/controller/src/ble_ll_iso.c
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,7 @@
#include <controller/ble_ll.h>
#include <controller/ble_ll_isoal.h>
#include <controller/ble_ll_iso.h>
#include <controller/ble_ll_tmr.h>

#if MYNEWT_VAL(BLE_LL_ISO)

Expand Down Expand Up @@ -129,11 +130,12 @@ ble_ll_iso_reset(void)
}

int
ble_ll_iso_data_handle(struct os_mbuf *om)
ble_ll_iso_data_in(struct os_mbuf *om)
{
struct ble_hci_iso *hci_iso;
struct ble_hci_iso_data *hci_iso_data;
struct ble_ll_iso_conn *conn;
struct ble_mbuf_hdr *blehdr;
uint16_t data_hdr_len;
uint16_t handle;
uint16_t conn_handle;
Expand All @@ -150,13 +152,24 @@ ble_ll_iso_data_handle(struct os_mbuf *om)
ts_flag = BLE_HCI_ISO_TS_FLAG(handle);
length = BLE_HCI_ISO_LENGTH(le16toh(hci_iso->length));

conn = ble_ll_iso_conn_find_by_handle(conn_handle);
if (!conn) {
os_mbuf_free_chain(om);
return BLE_ERR_UNK_CONN_ID;
}

data_hdr_len = 0;
if ((pb_flag == BLE_HCI_ISO_PB_FIRST) ||
(pb_flag == BLE_HCI_ISO_PB_COMPLETE)) {
blehdr = BLE_MBUF_HDR_PTR(om);
blehdr->txiso.packet_seq_num = ++conn->mux.sdu_counter;
blehdr->txiso.cpu_timestamp = ble_ll_tmr_get();

if (ts_flag) {
timestamp = get_le32(om->om_data + sizeof(*hci_iso));
data_hdr_len += sizeof(uint32_t);
}
blehdr->txiso.hci_timestamp = timestamp;

hci_iso_data = (void *)(om->om_data + sizeof(*hci_iso) + data_hdr_len);
data_hdr_len += sizeof(*hci_iso_data);
Expand All @@ -168,12 +181,6 @@ ble_ll_iso_data_handle(struct os_mbuf *om)
return BLE_ERR_MEM_CAPACITY;
}

conn = ble_ll_iso_conn_find_by_handle(conn_handle);
if (!conn) {
os_mbuf_free_chain(om);
return BLE_ERR_UNK_CONN_ID;
}

switch (pb_flag) {
case BLE_HCI_ISO_PB_FIRST:
BLE_LL_ASSERT(!conn->frag);
Expand All @@ -200,7 +207,7 @@ ble_ll_iso_data_handle(struct os_mbuf *om)
}

if (om) {
ble_ll_isoal_mux_sdu_enqueue(&conn->mux, om, timestamp);
ble_ll_isoal_mux_sdu_enqueue(&conn->mux, om);
}

return 0;
Expand All @@ -215,14 +222,17 @@ ble_ll_iso_pdu_get(struct ble_ll_iso_conn *conn, uint8_t idx, uint8_t *llid, voi
void
ble_ll_iso_conn_init(struct ble_ll_iso_conn *conn, uint16_t conn_handle,
uint8_t max_pdu, uint32_t iso_interval_us,
uint32_t sdu_interval_us, uint8_t bn, uint8_t pte)
uint32_t sdu_interval_us, uint8_t bn, uint8_t pte,
uint8_t framing)
{
os_sr_t sr;

memset(conn, 0, sizeof(*conn));

conn->handle = conn_handle;
ble_ll_isoal_mux_init(&conn->mux, max_pdu, iso_interval_us, sdu_interval_us, bn, pte);
ble_ll_isoal_mux_init(&conn->mux, max_pdu, iso_interval_us, sdu_interval_us,
bn, pte, BLE_LL_ISOAL_MUX_IS_FRAMED(framing),
framing == BLE_HCI_ISO_FRAMING_FRAMED_UNSEGMENTED);

OS_ENTER_CRITICAL(sr);
STAILQ_INSERT_TAIL(&ll_iso_conn_q, conn, iso_conn_q_next);
Expand All @@ -242,13 +252,14 @@ ble_ll_iso_conn_free(struct ble_ll_iso_conn *conn)
}

int
ble_ll_iso_event_start(struct ble_ll_iso_conn *conn, uint32_t timestamp)
ble_ll_iso_conn_event_start(struct ble_ll_iso_conn *conn, uint32_t timestamp)
{
return ble_ll_isoal_mux_event_start(&conn->mux, timestamp);
ble_ll_isoal_mux_event_start(&conn->mux, timestamp);
return 0;
}

int
ble_ll_iso_event_done(struct ble_ll_iso_conn *conn)
ble_ll_iso_conn_event_done(struct ble_ll_iso_conn *conn)
{
conn->num_completed_pkt += ble_ll_isoal_mux_event_done(&conn->mux);
return conn->num_completed_pkt;
Expand Down
29 changes: 14 additions & 15 deletions nimble/controller/src/ble_ll_iso_big.c
Original file line number Diff line number Diff line change
Expand Up @@ -86,8 +86,8 @@ struct big_params {
uint16_t max_sdu;
uint8_t max_pdu;
uint8_t phy;
uint8_t framing;
uint8_t interleaved : 1;
uint8_t framed : 1;
uint8_t encrypted : 1;
uint8_t broadcast_code[16];
};
Expand All @@ -110,6 +110,7 @@ struct ble_ll_iso_big {
uint8_t nse; /* 1-31 */
uint8_t interleaved : 1;
uint8_t framed : 1;
uint8_t framing_mode : 1;
uint8_t encrypted : 1;
uint8_t giv[8];
uint8_t gskd[16];
Expand Down Expand Up @@ -223,8 +224,8 @@ ble_ll_iso_big_biginfo_calc(struct ble_ll_iso_big *big, uint32_t seed_aa)
put_le24(buf, (big->irc << 20) | (big->bis_spacing));
buf += 3;

/* max_pdu, rfu */
put_le16(buf, big->max_pdu);
/* max_pdu, rfu, framing_mode */
put_le16(buf, big->max_pdu | (big->framing_mode) << 15);
buf += 2;

/* seed_access_address */
Expand All @@ -245,7 +246,8 @@ ble_ll_iso_big_biginfo_calc(struct ble_ll_iso_big *big, uint32_t seed_aa)
buf += 5;

/* bis_payload_cnt, framing */
memset(buf, 0x00, 5);
memset(buf, 0x01, 5);
buf[4] |= (big->framed << 7) & 0x80;
}

int
Expand Down Expand Up @@ -306,7 +308,7 @@ ble_ll_iso_big_biginfo_copy(struct ble_ll_iso_big *big, uint8_t *dptr,
*dptr++ = (counter >> 8) & 0xff;
*dptr++ = (counter >> 16) & 0xff;
*dptr++ = (counter >> 24) & 0xff;
*dptr++ = (counter >> 32) & 0xff;
*dptr++ = ((counter >> 32) & 0x7f) | ((big->framed << 7) & 0x80);

if (big->encrypted) {
memcpy(dptr, big->giv, 8);
Expand Down Expand Up @@ -799,8 +801,6 @@ ble_ll_iso_big_event_sched_cb(struct ble_ll_sched_item *sch)

ble_ll_tx_power_set(g_ble_ll_tx_power);

BLE_LL_ASSERT(!big->framed);

/* XXX calculate this in advance at the end of previous event? */
big->tx.subevents_rem = big->num_bis * big->nse;
STAILQ_FOREACH(bis, &big->bis_q, bis_q_next) {
Expand Down Expand Up @@ -982,13 +982,11 @@ ble_ll_iso_big_create(uint8_t big_handle, uint8_t adv_handle, uint8_t num_bis,
bis->num = big->num_bis;
bis->crc_init = (big->crc_init << 8) | (big->num_bis);

BLE_LL_ASSERT(!big->framed);

conn_handle = BLE_LL_CONN_HANDLE(BLE_LL_CONN_HANDLE_TYPE_BIS, idx);

ble_ll_iso_conn_init(&bis->conn, conn_handle, bp->max_pdu,
bp->iso_interval * 1250, bp->sdu_interval,
bp->bn, pte);
bp->bn, pte, bp->framing);
}

big_pool_free--;
Expand Down Expand Up @@ -1024,7 +1022,8 @@ ble_ll_iso_big_create(uint8_t big_handle, uint8_t adv_handle, uint8_t num_bis,
big->irc = bp->irc;
big->nse = bp->nse;
big->interleaved = bp->interleaved;
big->framed = bp->framed;
big->framed = bp->framing != BLE_HCI_ISO_FRAMING_UNFRAMED;
big->framing_mode = bp->framing == BLE_HCI_ISO_FRAMING_FRAMED_UNSEGMENTED;
big->encrypted = bp->encrypted;
big->sdu_interval = bp->sdu_interval;
big->iso_interval = bp->iso_interval;
Expand Down Expand Up @@ -1240,7 +1239,7 @@ ble_ll_iso_big_hci_create(const uint8_t *cmdbuf, uint8_t len)
!IN_RANGE(le16toh(cmd->max_sdu), 0x0001, 0x0fff) ||
!IN_RANGE(le16toh(cmd->max_transport_latency), 0x0005, 0x0fa0) ||
!IN_RANGE(cmd->rtn, 0x00, 0x1e) ||
(cmd->packing > 1) || (cmd->framing > 1) || (cmd->encryption) > 1) {
(cmd->packing > 1) || (cmd->framing > 2) || (cmd->encryption) > 1) {
return BLE_ERR_INV_HCI_CMD_PARMS;
}

Expand All @@ -1255,7 +1254,7 @@ ble_ll_iso_big_hci_create(const uint8_t *cmdbuf, uint8_t len)
bp.phy = BLE_PHY_CODED;
}
bp.interleaved = cmd->packing;
bp.framed = cmd->framing;
bp.framing = cmd->framing;
bp.encrypted = cmd->encryption;
memcpy(bp.broadcast_code, cmd->broadcast_code, 16);

Expand Down Expand Up @@ -1333,7 +1332,7 @@ ble_ll_iso_big_hci_create_test(const uint8_t *cmdbuf, uint8_t len)
bp.phy = BLE_PHY_CODED;
}
bp.interleaved = cmd->packing;
bp.framed = cmd->framing;
bp.framing = cmd->framing;
bp.encrypted = cmd->encryption;
memcpy(bp.broadcast_code, cmd->broadcast_code, 16);

Expand All @@ -1343,7 +1342,7 @@ ble_ll_iso_big_hci_create_test(const uint8_t *cmdbuf, uint8_t len)

iso_interval_us = bp.iso_interval * 1250;

if (!bp.framed) {
if (bp.framing == BLE_HCI_ISO_FRAMING_UNFRAMED) {
/* sdu_interval shall be an integer multiple of iso_interval */
if (iso_interval_us % bp.sdu_interval) {
return BLE_ERR_INV_HCI_CMD_PARMS;
Expand Down
Loading

0 comments on commit 3c9035a

Please sign in to comment.