Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

nimble/host: Add Initial Unicast implementation #1622

Draft
wants to merge 1 commit into
base: master
Choose a base branch
from
Draft
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
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
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);
}

rymanluk marked this conversation as resolved.
Show resolved Hide resolved
#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)
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@andrzej-kaczmarek please check if MYNEWT_VAL name is OK for you

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);
rymanluk marked this conversation as resolved.
Show resolved Hide resolved
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
49 changes: 49 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,11 @@ 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;

#if MYNEWT_VAL(BLE_ISO)
static uint16_t ble_iso_hci_buf_sz;
Fixed Show fixed Hide fixed
static uint8_t ble_iso_hci_max_pkts;
Fixed Show fixed Hide fixed
#endif

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

Expand Down Expand Up @@ -75,6 +80,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 +128,47 @@ 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;
}

/**
* Calculates the largest ISO payload that the controller can accept.
*/
uint16_t
ble_hs_iso_hci_max_iso_payload_sz(void)
{
/* As per BLE 5.1 Standard, Vol. 2, Part E, section 7.8.2:
* The LE_Read_Buffer_Size command is used to read the maximum size of the
* data portion of HCI LE ACL Data Packets sent from the Host to the
* Controller.
*/
return ble_iso_hci_buf_sz;
}
/**
* Increases the count of available controller ACL buffers.
*/

void
ble_hs_iso_hci_add_avail_pkts(uint16_t delta)
{
BLE_HS_DBG_ASSERT(ble_hs_locked_by_cur_task());

if (ble_iso_hci_avail_pkts + delta > UINT16_MAX) {
ble_hs_sched_reset(BLE_HS_ECONTROLLER);
} else {
ble_iso_hci_avail_pkts += delta;
}
}
#endif

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