Skip to content

Commit

Permalink
nimble/host: Add Initial unicast implementation
Browse files Browse the repository at this point in the history
This commit provides initial implementation ofunicast ISO in host.
  • Loading branch information
rymanluk authored and KKopyscinski committed Dec 8, 2023
1 parent bbba284 commit af6937b
Show file tree
Hide file tree
Showing 18 changed files with 1,417 additions and 15 deletions.
21 changes: 21 additions & 0 deletions nimble/controller/src/ble_ll_hci.c
Original file line number Diff line number Diff line change
Expand Up @@ -1282,6 +1282,27 @@ ble_ll_hci_le_cmd_proc(const uint8_t *cmdbuf, uint8_t len, uint16_t ocf,
break;
#endif /* BLE_LL_ISO_BROADCASTER */
#if MYNEWT_VAL(BLE_LL_ISO)
case BLE_HCI_OCF_LE_SET_CIG_PARAMS:
rc = ble_ll_iso_set_cig_param(cmdbuf, len, rspbuf, rsplen);
break;
case BLE_HCI_OCF_LE_CREATE_CIS:
rc = ble_ll_iso_create_cis(cmdbuf, len);
break;
case BLE_HCI_OCF_LE_REMOVE_CIG:
rc = ble_ll_iso_remove_cig(cmdbuf, len, rspbuf, rsplen);
break;
case BLE_HCI_OCF_LE_ACCEPT_CIS_REQ:
rc = ble_ll_iso_accept_cis_req(cmdbuf, len);
break;
case BLE_HCI_OCF_LE_REJECT_CIS_REQ:
rc = ble_ll_iso_reject_cis_req(cmdbuf, len);
break;
case BLE_HCI_OCF_LE_BIG_CREATE_SYNC:
rc = ble_ll_iso_big_create_sync(cmdbuf, len);
break;
case BLE_HCI_OCF_LE_BIG_TERMINATE_SYNC:
rc = ble_ll_iso_big_terminate_sync(cmdbuf,len);
break;
case BLE_HCI_OCF_LE_SETUP_ISO_DATA_PATH:
rc = ble_ll_isoal_hci_setup_iso_data_path(cmdbuf, len, rspbuf, rsplen);
break;
Expand Down
101 changes: 100 additions & 1 deletion nimble/host/include/host/ble_iso.h
Original file line number Diff line number Diff line change
Expand Up @@ -20,14 +20,25 @@
#ifndef H_BLE_ISO_
#define H_BLE_ISO_
#include "syscfg/syscfg.h"
#include <inttypes.h>

/** ISO event: BIG Create Completed */
#define BLE_ISO_EVENT_BIG_CREATE_COMPLETE 0

/** ISO event: BIG Terminate Completed */
#define BLE_ISO_EVENT_BIG_TERMINATE_COMPLETE 1

#include <inttypes.h>
/** ISO event: Connection Request */
#define BLE_ISO_EVENT_CONNECT_REQUEST 2

/** ISO event: CIS Connection Established */
#define BLE_ISO_EVENT_CIS_ESTABLISHED 3

/** ISO event: CIS Connection Terminated */
#define BLE_ISO_EVENT_CIS_DISCONNECTED 4

/** ISO event: ISO Data Received */
#define BLE_ISO_EVENT_DATA 5

struct ble_iso_big_desc
{
Expand Down Expand Up @@ -80,6 +91,59 @@ struct ble_iso_event {
uint16_t big_handle;
uint8_t reason;
} big_terminated;

/* Represents a reception of connection request to CIS. Valid for the
* following event types:
* o BLE_ISO_CONNECT_REQUEST_EVENT
*/
struct {
uint16_t conn_handle;
uint16_t cis_handle;
} cis_connect_req;

/* Represents an establishment of connection to CIS. Valid for the
* following event types:
* o BLE_ISO_CIS_ESTABLISHED_EVENT
*/
struct {
uint8_t status;
uint16_t cis_handle;
} cis_established;

/* Represents a termination of connection to CIS. Valid for the
* following event types:
* o BLE_ISO_CIS_DISCONNECTED_EVENT
*/
struct {
uint8_t status;
uint16_t cis_handle;
} cis_disconnected;

/* Represents sync established with BIG. Valid for the following
* event types:
* o BLE_ISO_BIG_ESTABLISHED_EVENT
*/
struct {
uint8_t status;
uint8_t big_handle;
uint8_t bis_cnt;
uint16_t bis[0];
} big_complete;

/* Represents sync lost with BIG. Valid for the following
* event types:
* o BLE_ISO_BIG_SYNC_LOST_EVENT
*/
struct {
uint8_t big_handle;
uint8_t reason;
} big_sync_lost;

/* BLE_ISO_DATA_EVENT - for both cis/bis_handles */
struct {
struct os_mbuf *om;
uint16_t handle;
} iso_data;
};
};

Expand All @@ -104,6 +168,30 @@ struct ble_iso_create_big_params {
void *cb_arg;
};

struct ble_iso_cig_params {
uint32_t sdu_c_to_p_itvl;
uint32_t sdu_p_to_c_itvl;
uint8_t sca;
uint8_t packing;
uint8_t framing;
uint8_t max_c_to_p_latency;
uint8_t max_p_to_c_latency;
#if MYNEWT_VAL(BLE_ISO_TEST)
uint8_t ft_c_to_p;
uint8_t ft_p_to_c;
uint16_t iso_itvl;
#endif
};

struct ble_iso_cis_params {
uint16_t max_sdu_c_to_p;
uint16_t max_sdu_p_to_c;
uint8_t phy_c_to_p;
uint8_t phy_p_to_c;
uint8_t rnt_c_to_p;
uint8_t rnt_p_to_c;
};

int ble_iso_create_big(const struct ble_iso_create_big_params *create_params,
const struct ble_iso_big_params *big_params);

Expand All @@ -117,6 +205,17 @@ ble_gap_rx_terminate_big_complete(const struct
ble_hci_ev_le_subev_terminate_big_complete
*ev);

int ble_iso_client_create_cig(struct ble_iso_cig_params *cig_params,
uint8_t cis_cnt,
struct ble_iso_cis_params *cis_params,
uint8_t *cig, uint8_t *cis_handles);

int ble_iso_client_remove_group(uint8_t cig_id);

int ble_iso_client_create_cis(uint8_t cig, uint8_t cis_cnt,
struct ble_hci_le_create_cis_params *params,
ble_iso_event_fn *cb, void *cb_arg);

int ble_iso_tx(uint16_t conn_handle, void *data, uint16_t data_len);

int ble_iso_init(void);
Expand Down
6 changes: 6 additions & 0 deletions nimble/host/src/ble_audio_broadcast.c
Original file line number Diff line number Diff line change
Expand Up @@ -233,6 +233,7 @@ ble_audio_broadcast_create(const struct ble_broadcast_create_params *params,
rc = ble_gap_ext_adv_configure(params->adv_instance,
params->extended_params, 0,
gap_cb, NULL);
assert(rc == 0);
if (rc) {
BLE_HS_LOG_ERROR("Could not configure the broadcast (rc=%d)\n", rc);
return 0;
Expand All @@ -246,6 +247,7 @@ ble_audio_broadcast_create(const struct ble_broadcast_create_params *params,

/* Set ext advertising data */
rc = ble_hs_adv_set_fields_mbuf(&adv_fields, adv_data);
assert(rc == 0);
if (rc) {
BLE_HS_LOG_ERROR("Failed to set extended advertising fields"
"(rc=%d)\n", rc);
Expand All @@ -255,6 +257,7 @@ ble_audio_broadcast_create(const struct ble_broadcast_create_params *params,
os_mbuf_append(adv_data, params->svc_data, params->svc_data_len);

rc = ble_gap_ext_adv_set_data(params->adv_instance, adv_data);
assert(rc == 0);
if (rc) {
BLE_HS_LOG_ERROR("Failed to set extended advertising data"
"(rc=%d)\n", rc);
Expand All @@ -269,20 +272,23 @@ ble_audio_broadcast_create(const struct ble_broadcast_create_params *params,
}

rc = ble_gap_periodic_adv_configure(params->adv_instance, params->periodic_params);
assert(rc == 0);
if (rc) {
BLE_HS_LOG_ERROR("failed to configure periodic advertising"
"(rc=%d)\n", rc);
return rc;
}

rc = ble_hs_adv_set_fields_mbuf(&per_adv_fields, adv_data);
assert(rc == 0);
if (rc) {
BLE_HS_LOG_ERROR("Failed to set periodic advertising fields"
"(rc=%d)\n", rc);
return rc;
}

rc = ble_gap_periodic_adv_set_data(params->adv_instance, adv_data, NULL);
assert(rc == 0);
if (rc) {
BLE_HS_LOG_ERROR("Failed to set periodic advertising data"
"(rc=%d)\n", rc);
Expand Down
9 changes: 8 additions & 1 deletion nimble/host/src/ble_gap.c
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,7 @@
#include "host/ble_hs_hci.h"
#include "ble_hs_priv.h"
#include "ble_gap_priv.h"
#include "ble_iso_priv.h"

#ifndef min
#define min(a, b) ((a) < (b) ? (a) : (b))
Expand Down Expand Up @@ -1208,7 +1209,10 @@ ble_gap_conn_broken(uint16_t conn_handle, int reason)

rc = ble_gap_find_snapshot(conn_handle, &snap);
if (rc != 0) {
#if MYNEWT_VAL(BLE_ISO)
/* No longer connected. */
ble_iso_disconnected_event(conn_handle, reason, false);
#endif
return;
}

Expand All @@ -1232,7 +1236,10 @@ ble_gap_conn_broken(uint16_t conn_handle, int reason)
ble_sm_connection_broken(conn_handle);
ble_gatts_connection_broken(conn_handle);
ble_gattc_connection_broken(conn_handle);
ble_hs_flow_connection_broken(conn_handle);;
ble_hs_flow_connection_broken(conn_handle);
#if MYNEWT_VAL(BLE_ISO)
ble_iso_disconnected_event(conn_handle, reason, true);
#endif

ble_hs_atomic_conn_delete(conn_handle);

Expand Down
51 changes: 48 additions & 3 deletions nimble/host/src/ble_hs.c
Original file line number Diff line number Diff line change
Expand Up @@ -75,6 +75,7 @@ static struct ble_npl_callout ble_hs_timer;
static struct ble_npl_eventq *ble_hs_evq;

static struct ble_mqueue ble_hs_rx_q;
static struct ble_mqueue ble_hs_rx_iso_q;

static struct ble_npl_mutex ble_hs_mutex;

Expand Down Expand Up @@ -225,6 +226,16 @@ ble_hs_process_rx_data_queue(void)
}
}

void
ble_hs_process_rx_iso_data_queue(void)
{
struct os_mbuf *om;

while ((om = ble_mqueue_get(&ble_hs_rx_iso_q)) != NULL) {
ble_hs_hci_evt_iso_process(om);
}
}

static int
ble_hs_wakeup_tx_conn(struct ble_hs_conn *conn)
{
Expand Down Expand Up @@ -302,6 +313,13 @@ ble_hs_clear_rx_queue(void)
while ((om = ble_mqueue_get(&ble_hs_rx_q)) != NULL) {
os_mbuf_free_chain(om);
}

#if MYNEWT_VAL(BLE_ISO)
while ((om = ble_mqueue_get(&ble_hs_rx_iso_q)) != NULL) {
os_mbuf_free_chain(om);
}
#endif

}

int
Expand Down Expand Up @@ -512,6 +530,12 @@ ble_hs_event_rx_data(struct ble_npl_event *ev)
ble_hs_process_rx_data_queue();
}

static void
ble_hs_event_rx_iso_data(struct ble_npl_event *ev)
{
ble_hs_process_rx_iso_data_queue();
}

static void
ble_hs_event_reset(struct ble_npl_event *ev)
{
Expand Down Expand Up @@ -676,6 +700,28 @@ ble_hs_rx_data(struct os_mbuf *om, void *arg)
return 0;
}

static int
ble_hs_rx_iso(struct os_mbuf *om, void *arg)
{
#if MYNEWT_VAL(BLE_ISO)
int rc;

/* If flow control is enabled, mark this packet with its corresponding
* connection handle.
*/

rc = ble_mqueue_put(&ble_hs_rx_iso_q, ble_hs_evq, om);
if (rc != 0) {
os_mbuf_free_chain(om);
return BLE_HS_EOS;
}

return 0;
#else
return BLE_HS_ENOTSUP;
#endif
}

/**
* Enqueues an ACL data packet for transmission. This function consumes the
* supplied mbuf, regardless of the outcome.
Expand Down Expand Up @@ -765,6 +811,7 @@ ble_hs_init(void)
ble_hs_stop_init();

ble_mqueue_init(&ble_hs_rx_q, ble_hs_event_rx_data, NULL);
ble_mqueue_init(&ble_hs_rx_iso_q, ble_hs_event_rx_iso_data, NULL);

rc = stats_init_and_reg(
STATS_HDR(ble_hs_stats), STATS_SIZE_INIT_PARMS(ble_hs_stats,
Expand Down Expand Up @@ -815,9 +862,7 @@ ble_transport_to_hs_acl_impl(struct os_mbuf *om)
int
ble_transport_to_hs_iso_impl(struct os_mbuf *om)
{
os_mbuf_free_chain(om);

return 0;
return ble_hs_rx_iso(om, NULL);
}

void
Expand Down
19 changes: 19 additions & 0 deletions nimble/host/src/ble_hs_hci.c
Original file line number Diff line number Diff line change
Expand Up @@ -33,6 +33,10 @@ static struct ble_hci_ev *ble_hs_hci_ack;
static uint16_t ble_hs_hci_buf_sz;
static uint8_t ble_hs_hci_max_pkts;


static uint16_t ble_iso_hci_buf_sz;

Check notice

Code scanning / CodeQL

Unused static variable Note

Static variable ble_iso_hci_buf_sz is never read.
static uint8_t ble_iso_hci_max_pkts;

Check notice

Code scanning / CodeQL

Unused static variable Note

Static variable ble_iso_hci_max_pkts is never read.

/* For now 32-bits of features is enough */
static uint32_t ble_hs_hci_sup_feat;

Expand Down Expand Up @@ -75,6 +79,9 @@ static struct os_mempool ble_hs_hci_frag_mempool;
* variable must only be accessed while the host mutex is locked.
*/
uint16_t ble_hs_hci_avail_pkts;
#if MYNEWT_VAL(BLE_ISO)
uint16_t ble_iso_hci_avail_pkts;
#endif

#if MYNEWT_VAL(BLE_HS_PHONY_HCI_ACKS)
static ble_hs_hci_phony_ack_fn *ble_hs_hci_phony_ack_cb;
Expand Down Expand Up @@ -120,6 +127,18 @@ ble_hs_hci_set_buf_sz(uint16_t pktlen, uint16_t max_pkts)
return 0;
}

#if MYNEWT_VAL(BLE_ISO)
int
ble_iso_hci_set_buf_sz(uint16_t iso_pktlen, uint16_t iso_max_pkts)
{
ble_iso_hci_buf_sz = iso_pktlen;
ble_iso_hci_max_pkts = iso_max_pkts;
ble_iso_hci_avail_pkts = iso_max_pkts;

return 0;
}
#endif

/**
* Increases the count of available controller ACL buffers.
*/
Expand Down
Loading

0 comments on commit af6937b

Please sign in to comment.