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:
parent
afe469eac7
commit
04dfcba792
|
@ -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. */
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -21,9 +21,6 @@ struct iso_data {
|
|||
|
||||
/** ISO connection handle */
|
||||
uint16_t handle;
|
||||
|
||||
/** ISO timestamp */
|
||||
uint32_t ts;
|
||||
};
|
||||
|
||||
enum {
|
||||
|
|
|
@ -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)
|
||||
|
|
Loading…
Reference in a new issue