Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
58 changes: 56 additions & 2 deletions nimble/controller/include/controller/ble_ll.h
Original file line number Diff line number Diff line change
Expand Up @@ -243,6 +243,9 @@ extern STATS_SECT_DECL(ble_ll_stats) ble_ll_stats;
#if MYNEWT_VAL(BLE_LL_ISO_BROADCASTER)
#define BLE_LL_STATE_BIG (9)
#endif
#if MYNEWT_VAL(BLE_LL_ISO_BROADCAST_SYNC)
#define BLE_LL_STATE_BIG_SYNC (10)
#endif

/* LL Features */
#define BLE_LL_FEAT_LE_ENCRYPTION (0x0000000000001)
Expand Down Expand Up @@ -300,8 +303,8 @@ extern STATS_SECT_DECL(ble_ll_stats) ble_ll_stats;
#define BLE_LL_CONN_CLEAR_FEATURE(connsm, feature) (connsm->conn_features &= ~(feature))

/* All the features which can be controlled by the Host */
#if MYNEWT_VAL(BLE_LL_CFG_FEAT_LL_ENHANCED_CONN_UPDATE) | \
MYNEWT_VAL(BLE_LL_ADV_CODING_SELECTION)
#if MYNEWT_VAL(BLE_LL_CFG_FEAT_LL_ENHANCED_CONN_UPDATE) | \
MYNEWT_VAL(BLE_LL_ADV_CODING_SELECTION) | MYNEWT_VAL(BLE_LL_ISO)
#define BLE_LL_HOST_CONTROLLED_FEATURES (1)
#else
#define BLE_LL_HOST_CONTROLLED_FEATURES (0)
Expand Down Expand Up @@ -462,6 +465,54 @@ struct ble_dev_addr
((((hdr) & BLE_LL_DATA_HDR_LLID_MASK) == BLE_LL_LLID_DATA_START) || \
(((hdr) & BLE_LL_DATA_HDR_LLID_MASK) == BLE_LL_LLID_DATA_FRAG))

/*
* Broadcast Isochronous Data Channel format
*
* -> Header (2 bytes)
* -> LSB contains llid, cssn and cstf
* -> MSB contains length (8 bits)
* -> Payload (0 to 251)
* -> MIC (0 or 4 bytes)
*/
#define BLE_LL_BIS_PDU_HDR_LLID_MASK (0x03)
#define BLE_LL_BIS_PDU_HDR_CSSN_MASK (0x1C)
#define BLE_LL_BIS_PDU_HDR_CSTF_MASK (0x20)
#define BLE_LL_BIS_PDU_HDR_RFU_MASK (0xC0)
#define BLE_LL_ISO_DATA_PAYLOAD_MAX (251)
#define BLE_LL_ISO_DATA_MIC_LEN (4)

/* Broadcast Isochronous PDU header LLID definitions */
#define BLE_LL_BIS_LLID_DATA_PDU_UNFRAMED_CMPLT (0b00)
#define BLE_LL_BIS_LLID_DATA_PDU_UNFRAMED_SC (0b01)
#define BLE_LL_BIS_LLID_DATA_PDU_FRAMED (0b10)
#define BLE_LL_BIS_LLID_CTRL_PDU (0b11)

#define BLE_LL_BIS_PDU_HDR_LLID(hdr) \
(((hdr) & BLE_LL_BIS_PDU_HDR_LLID_MASK) >> 0)
#define BLE_LL_BIS_PDU_HDR_CSSN(hdr) \
(((hdr) & BLE_LL_BIS_PDU_HDR_CSSN_MASK) >> 2)
#define BLE_LL_BIS_PDU_HDR_CSTF(hdr) \
(((hdr) & BLE_LL_BIS_PDU_HDR_CSTF_MASK) >> 5)

#define BLE_LL_BIS_LLID_IS_CTRL(hdr) \
(BLE_LL_BIS_PDU_HDR_LLID(hdr) == BLE_LL_BIS_LLID_CTRL_PDU)
#define BLE_LL_BIS_LLID_IS_DATA(hdr) \
((BLE_LL_BIS_PDU_HDR_LLID(hdr) == BLE_LL_BIS_LLID_DATA_PDU_UNFRAMED_CMPLT) || \
(BLE_LL_BIS_PDU_HDR_LLID(hdr) == BLE_LL_BIS_LLID_DATA_PDU_UNFRAMED_SC) || \
(BLE_LL_BIS_PDU_HDR_LLID(hdr) == BLE_LL_BIS_LLID_DATA_PDU_FRAMED))

#define BLE_LL_BIG_CTRL_CHAN_MAP_IND (0x00)
struct ble_ll_big_ctrl_chan_map_ind {
uint8_t chan_map[BLE_LL_CHAN_MAP_LEN];
uint16_t instant;
} __attribute__((packed));

#define BLE_LL_BIG_CTRL_TERM_IND (0x01)
struct ble_ll_big_ctrl_term_ind {
uint8_t reason;
uint16_t instant;
} __attribute__((packed));

/*
* CONNECT_REQ
* -> InitA (6 bytes)
Expand Down Expand Up @@ -581,6 +632,9 @@ int ble_ll_rx_start(uint8_t *rxbuf, uint8_t chan, struct ble_mbuf_hdr *hdr);
/* Called by the PHY when a packet reception ends */
int ble_ll_rx_end(uint8_t *rxbuf, struct ble_mbuf_hdr *rxhdr);

/* Called by the PHY when a packet reception ends */
int ble_ll_rx_early_end(const uint8_t *rxbuf, const struct ble_mbuf_hdr *rxhdr);

/* Helper callback to tx mbuf using ble_phy_tx() */
uint8_t ble_ll_tx_mbuf_pducb(uint8_t *dptr, void *pducb_arg, uint8_t *hdr_byte);
uint8_t ble_ll_tx_flat_mbuf_pducb(uint8_t *dptr, void *pducb_arg, uint8_t *hdr_byte);
Expand Down
76 changes: 11 additions & 65 deletions nimble/controller/include/controller/ble_ll_iso.h
Original file line number Diff line number Diff line change
Expand Up @@ -17,52 +17,16 @@
* under the License.
*/

#ifndef H_BLE_LL_ISO
#define H_BLE_LL_ISO
#ifndef H_BLE_LL_ISO_
#define H_BLE_LL_ISO_

#include <stdint.h>
#include <controller/ble_ll_isoal.h>
#include <os/os_mbuf.h>

#ifdef __cplusplus
extern "C" {
#endif

struct ble_ll_iso_data_path {
uint8_t data_path_id;
uint8_t enabled : 1;
};
struct ble_ll_iso_test_mode {
struct {
uint32_t rand;
uint8_t payload_type;
uint8_t enabled : 1;
} transmit;
};
struct ble_ll_iso_conn {
/* Connection handle */
uint16_t handle;

/* Maximum SDU size */
uint16_t max_sdu;

/* ISO Data Path */
struct ble_ll_iso_data_path data_path;

/* ISO Test Mode */
struct ble_ll_iso_test_mode test_mode;

/* ISOAL Multiplexer */
struct ble_ll_isoal_mux mux;

/* HCI SDU Fragment */
struct os_mbuf *frag;

/* Number of Completed Packets */
uint16_t num_completed_pkt;

STAILQ_ENTRY(ble_ll_iso_conn) iso_conn_q_next;
};

/* HCI command handlers */
int ble_ll_iso_read_tx_sync(const uint8_t *cmdbuf, uint8_t len, uint8_t *rspbuf, uint8_t *rsplen);
int ble_ll_iso_set_cig_param(const uint8_t *cmdbuf, uint8_t len, uint8_t *rspbuf, uint8_t *rsplen);
Expand All @@ -74,41 +38,23 @@ int ble_ll_iso_reject_cis_req(const uint8_t *cmdbuf, uint8_t len);
int ble_ll_iso_create_big(const uint8_t *cmdbuf, uint8_t len);
int ble_ll_iso_create_big_test(const uint8_t *cmdbuf, uint8_t len);
int ble_ll_iso_terminate_big(const uint8_t *cmdbuf, uint8_t len);
int ble_ll_iso_big_create_sync(const uint8_t *cmdbuf, uint8_t len);
int ble_ll_iso_big_create_sync(const uint8_t *cmdbuf, uint8_t len,
uint8_t *rspbuf, uint8_t *rsplen);
int ble_ll_iso_big_terminate_sync(const uint8_t *cmdbuf, uint8_t len);
int ble_ll_iso_setup_iso_data_path(const uint8_t *cmdbuf, uint8_t len, uint8_t *rspbuf, uint8_t *rsplen);
int ble_ll_iso_remove_iso_data_path(const uint8_t *cmdbuf, uint8_t len, uint8_t *rspbuf, uint8_t *rsplen);
int ble_ll_iso_transmit_test(const uint8_t *cmdbuf, uint8_t len, uint8_t *rspbuf, uint8_t *rsplen);
int ble_ll_iso_receive_test(const uint8_t *cmdbuf, uint8_t len);
int ble_ll_iso_read_counters_test(const uint8_t *cmdbuf, uint8_t len);
int ble_ll_iso_receive_test(const uint8_t *cmdbuf, uint8_t len,
uint8_t *rspbuf, uint8_t *rsplen);
int ble_ll_iso_read_counters_test(const uint8_t *cmdbuf, uint8_t len,
uint8_t *rspbuf, uint8_t *rsplen);
int ble_ll_iso_end_test(const uint8_t *cmdbuf, uint8_t len, uint8_t *rspbuf, uint8_t *rsplen);

void ble_ll_iso_init(void);
void ble_ll_iso_reset(void);

/* ISO Data handler */
int ble_ll_iso_data_in(struct os_mbuf *om);

int ble_ll_iso_pdu_get(struct ble_ll_iso_conn *conn, uint8_t idx, uint32_t pkt_counter, uint8_t *llid, void *dptr);

struct ble_ll_iso_conn_init_param {
uint32_t iso_interval_us;
uint32_t sdu_interval_us;
uint16_t conn_handle;
uint16_t max_sdu;
uint8_t max_pdu;
uint8_t framing;
uint8_t pte;
uint8_t bn;
};

void ble_ll_iso_conn_init(struct ble_ll_iso_conn *conn, struct ble_ll_iso_conn_init_param *param);
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);
int ble_ll_iso_conn_event_done(struct ble_ll_iso_conn *conn);

struct ble_ll_iso_conn *ble_ll_iso_conn_find_by_handle(uint16_t conn_handle);
/* HCI ISO Data SDU handler */
int ble_ll_hci_iso_data_in(struct os_mbuf *om);

#ifdef __cplusplus
}
Expand Down
51 changes: 51 additions & 0 deletions nimble/controller/include/controller/ble_ll_iso_big_sync.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,51 @@
/*
* Licensed to the Apache Software Foundation (ASF) under one
* or more contributor license agreements. See the NOTICE file
* distributed with this work for additional information
* regarding copyright ownership. The ASF licenses this file
* to you under the Apache License, Version 2.0 (the
* "License"); you may not use this file except in compliance
* with the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing,
* software distributed under the License is distributed on an
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
* KIND, either express or implied. See the License for the
* specific language governing permissions and limitations
* under the License.
*/

#ifndef H_BLE_LL_ISO_BIG_SYNC_
#define H_BLE_LL_ISO_BIG_SYNC_

#ifdef __cplusplus
extern "C" {
#endif

#if MYNEWT_VAL(BLE_LL_ISO_BROADCAST_SYNC)

int ble_ll_iso_big_sync_rx_isr_start(uint8_t pdu_type, struct ble_mbuf_hdr *rxhdr);
int ble_ll_iso_big_sync_rx_isr_end(uint8_t *rxbuf, struct ble_mbuf_hdr *rxhdr);
int ble_ll_iso_big_sync_rx_isr_early_end(const uint8_t *rxbuf,
const struct ble_mbuf_hdr *rxhdr);
void ble_ll_iso_big_sync_rx_pdu_in(struct os_mbuf **rxpdu, struct ble_mbuf_hdr *hdr);

void ble_ll_iso_big_sync_wfr_timer_exp(void);
void ble_ll_iso_big_sync_halt(void);

int ble_ll_iso_big_sync_hci_create(const uint8_t *cmdbuf, uint8_t len);
int ble_ll_iso_big_sync_hci_terminate(const uint8_t *cmdbuf, uint8_t len,
uint8_t *rspbuf, uint8_t *rsplen);

void ble_ll_iso_big_sync_init(void);
void ble_ll_iso_big_sync_reset(void);

#endif /* BLE_LL_ISO_BROADCAST_SYNC */

#ifdef __cplusplus
}
#endif

#endif /* H_BLE_LL_ISO_BIG_SYNC_ */
111 changes: 79 additions & 32 deletions nimble/controller/include/controller/ble_ll_isoal.h
Original file line number Diff line number Diff line change
Expand Up @@ -21,31 +21,53 @@
#define H_BLE_LL_ISOAL_

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

#ifdef __cplusplus
extern "C" {
#endif

#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_TIME_OFFSET_LEN 3

struct ble_ll_isoal_config {
/* ISO Interval */
uint32_t iso_interval_us;
/* SDU Interval */
uint32_t sdu_interval_us;
/* Maximum SDU size */
uint16_t max_sdu;
/* Max PDU length */
uint8_t max_pdu;
/* Burst Number */
uint8_t bn;
/**/
uint8_t pte;
/* Framed */
uint8_t framed : 1;
/* Framing mode = segmentable/unsegmented */
uint8_t unsegmented : 1;
};

struct ble_ll_isoal_mux {
struct ble_ll_isoal_config config;
#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 */
/* Number of SDUs available for the current event */
uint8_t sdu_in_event;

/* Burst Number */
uint8_t bn;

STAILQ_HEAD(, os_mbuf_pkthdr) sdu_q;
uint16_t sdu_q_len;

Expand All @@ -57,39 +79,64 @@ struct ble_ll_isoal_mux {

/* 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)
void ble_ll_isoal_mux_init(struct ble_ll_isoal_mux *mux,
struct ble_ll_isoal_config *config);
void ble_ll_isoal_mux_reset(struct ble_ll_isoal_mux *mux);
int 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_put(struct ble_ll_isoal_mux *mux, struct os_mbuf *om);

#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)
/* Forward declaration */
struct ble_ll_isoal_demux;

#define BLE_LL_ISOAL_MUX_IS_FRAMED(framing) \
((framing) == BLE_HCI_ISO_FRAMING_FRAMED_SEGMENTABLE || \
(framing) == BLE_HCI_ISO_FRAMING_FRAMED_UNSEGMENTED)
/* ISOAL Demultiplexer callback structure */
struct ble_ll_isoal_demux_cb {
void (*sdu_cb)(struct ble_ll_isoal_demux *demux, const struct os_mbuf *om,
uint32_t timestamp, uint16_t seq_num, bool valid);
};

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, bool framed,
uint8_t framing_mode);
void ble_ll_isoal_mux_free(struct ble_ll_isoal_mux *mux);
struct ble_ll_isoal_demux {
struct ble_ll_isoal_config config;

int 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);
uint8_t active;

int ble_ll_isoal_mux_pdu_get(struct ble_ll_isoal_mux *mux, uint8_t idx,
uint8_t *llid, void *dptr);
/* 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 expected for the current event */
uint8_t sdu_in_event;

STAILQ_HEAD(, os_mbuf_pkthdr) pdu_q;

uint32_t sdu_counter;

uint32_t ref_time;
uint32_t last_rx_timestamp;

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

void ble_ll_isoal_init(void);
void ble_ll_isoal_reset(void);
const struct ble_ll_isoal_demux_cb *cb;
};

void ble_ll_isoal_demux_init(struct ble_ll_isoal_demux *demux,
struct ble_ll_isoal_config *config);
void ble_ll_isoal_demux_reset(struct ble_ll_isoal_demux *demux);
int ble_ll_isoal_demux_event_start(struct ble_ll_isoal_demux *demux, uint32_t timestamp);
int ble_ll_isoal_demux_event_done(struct ble_ll_isoal_demux *demux);
void ble_ll_isoal_demux_pdu_put(struct ble_ll_isoal_demux *demux, uint8_t idx,
struct os_mbuf *om);

static inline void
ble_ll_isoal_demux_cb_set(struct ble_ll_isoal_demux *demux,
const struct ble_ll_isoal_demux_cb *cb)
{
demux->cb = cb;
}

#ifdef __cplusplus
}
Expand Down
Loading