Bluetooth: ISO: Add sequence number to ISO data packets

The sequence number is needed in the appliaction layer to detect lost
packets in the ISO stream in cases where the timestamp is not included.
(Sequence number is mandatory to include where timestamp is optional).
The API for the public metadata have been moved to a public header file.

As the size of the ISO meta data exceeds the default 4 octets net_buf
user_data the public ISO metadata have been moved into a seperate array.
The internal metadata is still stored in net_buf user_data.

This also fixed the user_data overflow on 32 bit systems, caused by
writing the ts into user_data on index 4 to 7, which is outside the 4
allocated bytes.

Signed-off-by: Casper Bonde <casper_bonde@bose.com>
This commit is contained in:
Casper Bonde 2021-03-29 10:00:44 +02:00 committed by Carles Cufí
parent afe469eac7
commit 04dfcba792
6 changed files with 33 additions and 13 deletions

View file

@ -138,6 +138,15 @@ struct bt_iso_chan_path {
uint8_t cc[0];
};
/** @brief ISO Meta Data structure for received ISO packets. */
struct bt_iso_recv_info {
/** ISO timestamp - valid only if the Bluetooth controller includes it */
uint32_t ts;
/** ISO Pkt Seq no of the first fragment in the SDU */
uint16_t sn;
};
/** Opaque type representing an Broadcast Isochronous Group (BIG). */
struct bt_iso_big;
@ -271,8 +280,13 @@ struct bt_iso_chan_ops {
*
* @param chan The channel receiving data.
* @param buf Buffer containing incoming data.
* @param info Pointer to the metadata for the buffer. The lifetime of the
* pointer is linked to the lifetime of the net_buf.
* Metadata such as sequence number and timestamp can be
* provided by the bluetooth controller.
*/
void (*recv)(struct bt_iso_chan *chan, struct net_buf *buf);
void (*recv)(struct bt_iso_chan *chan, const struct bt_iso_recv_info *info,
struct net_buf *buf);
};
/** @brief ISO Server structure. */

View file

@ -209,7 +209,8 @@ static struct bt_le_per_adv_sync_cb sync_callbacks = {
#define BIS_ISO_CHAN_COUNT 1
static void iso_recv(struct bt_iso_chan *chan, struct net_buf *buf)
static void iso_recv(struct bt_iso_chan *chan, const struct bt_iso_recv_info *info,
struct net_buf *buf)
{
char data_str[128];
size_t str_len;

View file

@ -87,7 +87,8 @@ static void iso_print_data(uint8_t *data, size_t data_len)
printk("\t %s\n", data_str);
}
static void iso_recv(struct bt_iso_chan *chan, struct net_buf *buf)
static void iso_recv(struct bt_iso_chan *chan, const struct bt_iso_recv_info *info,
struct net_buf *buf)
{
printk("Incoming data channel %p len %u\n", chan, buf->len);
iso_print_data(buf->data, buf->len);

View file

@ -28,6 +28,9 @@ NET_BUF_POOL_FIXED_DEFINE(iso_tx_pool, CONFIG_BT_ISO_TX_BUF_COUNT,
NET_BUF_POOL_FIXED_DEFINE(iso_rx_pool, CONFIG_BT_ISO_RX_BUF_COUNT,
CONFIG_BT_ISO_RX_MTU, NULL);
static struct bt_iso_recv_info iso_info_data[CONFIG_BT_ISO_RX_BUF_COUNT];
#define iso_info(buf) (&iso_info_data[net_buf_id(buf)])
#if CONFIG_BT_ISO_TX_FRAG_COUNT > 0
NET_BUF_POOL_FIXED_DEFINE(iso_frag_pool, CONFIG_BT_ISO_TX_FRAG_COUNT,
CONFIG_BT_ISO_TX_MTU, NULL);
@ -1112,7 +1115,7 @@ void bt_iso_recv(struct bt_conn *conn, struct net_buf *buf, uint8_t flags)
struct bt_hci_iso_data_hdr *hdr;
struct bt_iso_chan *chan;
uint8_t pb, ts;
uint16_t len;
uint16_t len, pkt_seq_no;
pb = bt_iso_flags_pb(flags);
ts = bt_iso_flags_ts(flags);
@ -1134,24 +1137,26 @@ void bt_iso_recv(struct bt_conn *conn, struct net_buf *buf, uint8_t flags)
struct bt_hci_iso_ts_data_hdr *ts_hdr;
ts_hdr = net_buf_pull_mem(buf, sizeof(*ts_hdr));
iso(buf)->ts = sys_le32_to_cpu(ts_hdr->ts);
iso_info(buf)->ts = sys_le32_to_cpu(ts_hdr->ts);
hdr = &ts_hdr->data;
} else {
hdr = net_buf_pull_mem(buf, sizeof(*hdr));
/* TODO: Generate a timestamp? */
iso(buf)->ts = 0x00000000;
iso_info(buf)->ts = 0x00000000;
}
len = sys_le16_to_cpu(hdr->slen);
flags = bt_iso_pkt_flags(len);
len = bt_iso_pkt_len(len);
pkt_seq_no = sys_le16_to_cpu(hdr->sn);
iso_info(buf)->sn = pkt_seq_no;
/* TODO: Drop the packet if NOP? */
BT_DBG("%s, len %u total %u flags 0x%02x timestamp %u",
pb == BT_ISO_START ? "Start" : "Single", buf->len, len,
flags, iso(buf)->ts);
flags, iso_info(buf)->ts);
if (conn->rx) {
BT_ERR("Unexpected ISO %s fragment",
@ -1230,7 +1235,7 @@ void bt_iso_recv(struct bt_conn *conn, struct net_buf *buf, uint8_t flags)
SYS_SLIST_FOR_EACH_CONTAINER(&conn->channels, chan, node) {
if (chan->ops->recv) {
chan->ops->recv(chan, conn->rx);
chan->ops->recv(chan, iso_info(conn->rx), conn->rx);
}
}

View file

@ -21,9 +21,6 @@ struct iso_data {
/** ISO connection handle */
uint16_t handle;
/** ISO timestamp */
uint32_t ts;
};
enum {

View file

@ -24,9 +24,11 @@
#include "bt.h"
static void iso_recv(struct bt_iso_chan *chan, struct net_buf *buf)
static void iso_recv(struct bt_iso_chan *chan, const struct bt_iso_recv_info *info,
struct net_buf *buf)
{
printk("Incoming data channel %p len %u\n", chan, buf->len);
printk("Incoming data channel %p len %u, seq: %d, ts: %d\n", chan, buf->len,
info->sn, info->ts);
}
static void iso_connected(struct bt_iso_chan *chan)