mirror of
https://github.com/espressif/esp-nimble.git
synced 2026-07-28 05:47:45 +00:00
nimble/host: Add initial periodic adverting host support
This patch adds the implementation for periodic advertising nd discovery, which is available when BLE_PERIODIC_ADV is enabled
This commit is contained in:
committed by
Łukasz Rymanowski
parent
95bb7fe646
commit
67844daa24
@@ -2106,7 +2106,7 @@ ble_ll_adv_set_scan_rsp_data(uint8_t *cmd, uint8_t cmd_len, uint8_t instance,
|
||||
}
|
||||
|
||||
switch (operation) {
|
||||
case BLE_HCI_LE_SET_EXT_SCAN_RSP_DATA_OPER_COMPLETE:
|
||||
case BLE_HCI_LE_SET_DATA_OPER_COMPLETE:
|
||||
if (advsm->props & BLE_HCI_LE_SET_EXT_ADV_PROP_LEGACY) {
|
||||
if (datalen > BLE_SCAN_RSP_LEGACY_DATA_MAX_LEN) {
|
||||
return BLE_ERR_INV_HCI_CMD_PARMS;
|
||||
@@ -2115,10 +2115,10 @@ ble_ll_adv_set_scan_rsp_data(uint8_t *cmd, uint8_t cmd_len, uint8_t instance,
|
||||
|
||||
break;
|
||||
#if MYNEWT_VAL(BLE_LL_CFG_FEAT_LL_EXT_ADV)
|
||||
case BLE_HCI_LE_SET_EXT_SCAN_RSP_DATA_OPER_LAST:
|
||||
case BLE_HCI_LE_SET_DATA_OPER_LAST:
|
||||
/* TODO mark scan rsp as complete? */
|
||||
/* fall through */
|
||||
case BLE_HCI_LE_SET_EXT_SCAN_RSP_DATA_OPER_INT:
|
||||
case BLE_HCI_LE_SET_DATA_OPER_INT:
|
||||
if (!advsm->scan_rsp_data) {
|
||||
return BLE_ERR_INV_HCI_CMD_PARMS;
|
||||
}
|
||||
@@ -2135,7 +2135,7 @@ ble_ll_adv_set_scan_rsp_data(uint8_t *cmd, uint8_t cmd_len, uint8_t instance,
|
||||
return BLE_ERR_INV_HCI_CMD_PARMS;
|
||||
}
|
||||
break;
|
||||
case BLE_HCI_LE_SET_EXT_SCAN_RSP_DATA_OPER_FIRST:
|
||||
case BLE_HCI_LE_SET_DATA_OPER_FIRST:
|
||||
if (advsm->props & BLE_HCI_LE_SET_EXT_ADV_PROP_LEGACY) {
|
||||
return BLE_ERR_INV_HCI_CMD_PARMS;
|
||||
}
|
||||
@@ -2154,8 +2154,8 @@ ble_ll_adv_set_scan_rsp_data(uint8_t *cmd, uint8_t cmd_len, uint8_t instance,
|
||||
return BLE_ERR_INV_HCI_CMD_PARMS;
|
||||
}
|
||||
|
||||
new_data = (operation == BLE_HCI_LE_SET_EXT_SCAN_RSP_DATA_OPER_COMPLETE) ||
|
||||
(operation == BLE_HCI_LE_SET_EXT_SCAN_RSP_DATA_OPER_FIRST);
|
||||
new_data = (operation == BLE_HCI_LE_SET_DATA_OPER_COMPLETE) ||
|
||||
(operation == BLE_HCI_LE_SET_DATA_OPER_FIRST);
|
||||
|
||||
if (advsm->adv_enabled) {
|
||||
if (advsm->new_scan_rsp_data) {
|
||||
@@ -2234,7 +2234,7 @@ ble_ll_adv_set_adv_data(uint8_t *cmd, uint8_t cmd_len, uint8_t instance,
|
||||
}
|
||||
|
||||
switch (operation) {
|
||||
case BLE_HCI_LE_SET_EXT_ADV_DATA_OPER_COMPLETE:
|
||||
case BLE_HCI_LE_SET_DATA_OPER_COMPLETE:
|
||||
if (advsm->props & BLE_HCI_LE_SET_EXT_ADV_PROP_LEGACY) {
|
||||
if (datalen > BLE_ADV_LEGACY_DATA_MAX_LEN) {
|
||||
return BLE_ERR_INV_HCI_CMD_PARMS;
|
||||
@@ -2245,7 +2245,7 @@ ble_ll_adv_set_adv_data(uint8_t *cmd, uint8_t cmd_len, uint8_t instance,
|
||||
|
||||
break;
|
||||
#if MYNEWT_VAL(BLE_LL_CFG_FEAT_LL_EXT_ADV)
|
||||
case BLE_HCI_LE_SET_EXT_ADV_DATA_OPER_UNCHANGED:
|
||||
case BLE_HCI_LE_SET_DATA_OPER_UNCHANGED:
|
||||
if (advsm->props & BLE_HCI_LE_SET_EXT_ADV_PROP_LEGACY) {
|
||||
return BLE_ERR_INV_HCI_CMD_PARMS;
|
||||
}
|
||||
@@ -2257,10 +2257,10 @@ ble_ll_adv_set_adv_data(uint8_t *cmd, uint8_t cmd_len, uint8_t instance,
|
||||
/* update DID only */
|
||||
ble_ll_adv_update_did(advsm);
|
||||
return BLE_ERR_SUCCESS;
|
||||
case BLE_HCI_LE_SET_EXT_ADV_DATA_OPER_LAST:
|
||||
case BLE_HCI_LE_SET_DATA_OPER_LAST:
|
||||
ble_ll_adv_flags_clear(advsm, BLE_LL_ADV_SM_FLAG_ADV_DATA_INCOMPLETE);
|
||||
/* fall through */
|
||||
case BLE_HCI_LE_SET_EXT_ADV_DATA_OPER_INT:
|
||||
case BLE_HCI_LE_SET_DATA_OPER_INT:
|
||||
if (!advsm->adv_data) {
|
||||
return BLE_ERR_INV_HCI_CMD_PARMS;
|
||||
}
|
||||
@@ -2277,7 +2277,7 @@ ble_ll_adv_set_adv_data(uint8_t *cmd, uint8_t cmd_len, uint8_t instance,
|
||||
return BLE_ERR_CMD_DISALLOWED;
|
||||
}
|
||||
break;
|
||||
case BLE_HCI_LE_SET_EXT_ADV_DATA_OPER_FIRST:
|
||||
case BLE_HCI_LE_SET_DATA_OPER_FIRST:
|
||||
if (advsm->props & BLE_HCI_LE_SET_EXT_ADV_PROP_LEGACY) {
|
||||
return BLE_ERR_INV_HCI_CMD_PARMS;
|
||||
}
|
||||
@@ -2297,8 +2297,8 @@ ble_ll_adv_set_adv_data(uint8_t *cmd, uint8_t cmd_len, uint8_t instance,
|
||||
return BLE_ERR_INV_HCI_CMD_PARMS;
|
||||
}
|
||||
|
||||
new_data = (operation == BLE_HCI_LE_SET_EXT_ADV_DATA_OPER_COMPLETE) ||
|
||||
(operation == BLE_HCI_LE_SET_EXT_ADV_DATA_OPER_FIRST);
|
||||
new_data = (operation == BLE_HCI_LE_SET_DATA_OPER_COMPLETE) ||
|
||||
(operation == BLE_HCI_LE_SET_DATA_OPER_FIRST);
|
||||
|
||||
if (advsm->adv_enabled) {
|
||||
if (advsm->new_adv_data) {
|
||||
|
||||
@@ -696,16 +696,16 @@ ble_ll_is_valid_adv_mode(uint8_t ocf)
|
||||
case BLE_HCI_OCF_LE_RD_NUM_OF_ADV_SETS:
|
||||
case BLE_HCI_OCF_LE_REMOVE_ADV_SET:
|
||||
case BLE_HCI_OCF_LE_CLEAR_ADV_SETS:
|
||||
case BLE_HCI_OCF_LE_SET_PER_ADV_PARAMS:
|
||||
case BLE_HCI_OCF_LE_SET_PER_ADV_DATA:
|
||||
case BLE_HCI_OCF_LE_SET_PER_ADV_ENABLE:
|
||||
case BLE_HCI_OCF_LE_PER_ADV_CREATE_SYNC:
|
||||
case BLE_HCI_OCF_LE_PER_ADV_CREATE_SYNC_CANCEL:
|
||||
case BLE_HCI_OCF_LE_PER_ADV_TERM_SYNC:
|
||||
case BLE_HCI_OCF_LE_ADD_DEV_TO_PER_ADV_LIST:
|
||||
case BLE_HCI_OCF_LE_REM_DEV_FROM_PER_ADV_LIST:
|
||||
case BLE_HCI_OCF_LE_CLEAR_PER_ADV_LIST:
|
||||
case BLE_HCI_OCF_LE_RD_PER_ADV_LIST_SIZE:
|
||||
case BLE_HCI_OCF_LE_SET_PERIODIC_ADV_PARAMS:
|
||||
case BLE_HCI_OCF_LE_SET_PERIODIC_ADV_DATA:
|
||||
case BLE_HCI_OCF_LE_SET_PERIODIC_ADV_ENABLE:
|
||||
case BLE_HCI_OCF_LE_PERIODIC_ADV_CREATE_SYNC:
|
||||
case BLE_HCI_OCF_LE_PERIODIC_ADV_CREATE_SYNC_CANCEL:
|
||||
case BLE_HCI_OCF_LE_PERIODIC_ADV_TERM_SYNC:
|
||||
case BLE_HCI_OCF_LE_ADD_DEV_TO_PERIODIC_ADV_LIST:
|
||||
case BLE_HCI_OCF_LE_REM_DEV_FROM_PERIODIC_ADV_LIST:
|
||||
case BLE_HCI_OCF_LE_CLEAR_PERIODIC_ADV_LIST:
|
||||
case BLE_HCI_OCF_LE_RD_PERIODIC_ADV_LIST_SIZE:
|
||||
if (hci_adv_mode == ADV_MODE_LEGACY) {
|
||||
return false;
|
||||
}
|
||||
@@ -859,13 +859,13 @@ ble_ll_hci_le_cmd_proc(uint8_t *cmdbuf, uint16_t ocf, uint8_t *rsplen,
|
||||
case BLE_HCI_OCF_LE_SET_ADV_DATA:
|
||||
if (len == BLE_HCI_SET_ADV_DATA_LEN) {
|
||||
rc = ble_ll_adv_set_adv_data(cmdbuf, len, 0,
|
||||
BLE_HCI_LE_SET_EXT_ADV_DATA_OPER_COMPLETE);
|
||||
BLE_HCI_LE_SET_DATA_OPER_COMPLETE);
|
||||
}
|
||||
break;
|
||||
case BLE_HCI_OCF_LE_SET_SCAN_RSP_DATA:
|
||||
if (len == BLE_HCI_SET_SCAN_RSP_DATA_LEN) {
|
||||
rc = ble_ll_adv_set_scan_rsp_data(cmdbuf, len, 0,
|
||||
BLE_HCI_LE_SET_EXT_SCAN_RSP_DATA_OPER_COMPLETE);
|
||||
BLE_HCI_LE_SET_DATA_OPER_COMPLETE);
|
||||
}
|
||||
break;
|
||||
case BLE_HCI_OCF_LE_SET_ADV_ENABLE:
|
||||
|
||||
@@ -124,6 +124,9 @@ struct hci_conn_update;
|
||||
#define BLE_GAP_EVENT_REPEAT_PAIRING 17
|
||||
#define BLE_GAP_EVENT_PHY_UPDATE_COMPLETE 18
|
||||
#define BLE_GAP_EVENT_EXT_DISC 19
|
||||
#define BLE_GAP_EVENT_PERIODIC_ADV_SYNC_ESTAB 20
|
||||
#define BLE_GAP_EVENT_PERIODIC_DISC 21
|
||||
#define BLE_GAP_EVENT_PERIODIC_ADV_SYNC_LOST 22
|
||||
|
||||
/*** Reason codes for the subscribe GAP event. */
|
||||
|
||||
@@ -708,6 +711,46 @@ struct ble_gap_event {
|
||||
uint8_t tx_phy;
|
||||
uint8_t rx_phy;
|
||||
} phy_updated;
|
||||
#if MYNEWT_VAL(BLE_EXT_ADV) && MYNEWT_VAL(BLE_PERIODIC_ADV)
|
||||
/**
|
||||
* Represents an periodic advertising sync established during discovery
|
||||
* procedure. Valid for the following event types:
|
||||
* o BLE_GAP_EVENT_PERIODIC_ADV_SYNC_ESTAB
|
||||
*/
|
||||
struct {
|
||||
uint8_t status;
|
||||
uint16_t sync_handle;
|
||||
uint8_t sid;
|
||||
uint8_t adv_addr_type;
|
||||
uint8_t adv_addr[6];
|
||||
uint8_t adv_phy;
|
||||
uint16_t per_adv_ival;
|
||||
uint8_t adv_clk_accuracy;
|
||||
} periodic_adv_sync_estab;
|
||||
|
||||
/**
|
||||
* Represents a Periodic advertising report received during discovery
|
||||
* procedure. Valid for the following event types:
|
||||
* o BLE_GAP_EVENT_PERIODIC_DISC
|
||||
*/
|
||||
struct {
|
||||
uint16_t sync_handle;
|
||||
uint8_t tx_power;
|
||||
int8_t rssi;
|
||||
uint8_t data_status;
|
||||
uint8_t data_length;
|
||||
uint8_t *data;
|
||||
} periodic_disc;
|
||||
|
||||
/**
|
||||
* Represents an periodic advertising sync Lost during discovery
|
||||
* procedure. Valid for the following event types:
|
||||
* o BLE_GAP_EVENT_PERIODIC_ADV_SYNC_LOST
|
||||
*/
|
||||
struct {
|
||||
uint16_t sync_handle;
|
||||
} periodic_adv_sync_lost;
|
||||
#endif
|
||||
};
|
||||
};
|
||||
|
||||
@@ -903,6 +946,15 @@ struct ble_gap_ext_adv_params {
|
||||
uint8_t sid;
|
||||
};
|
||||
|
||||
#if MYNEWT_VAL(BLE_PERIODIC_ADV)
|
||||
struct ble_gap_periodic_adv_params {
|
||||
unsigned int include_tx_power:1;
|
||||
|
||||
uint16_t itvl_min;
|
||||
uint16_t itvl_max;
|
||||
};
|
||||
#endif
|
||||
|
||||
int ble_gap_ext_adv_configure(uint8_t instance,
|
||||
const struct ble_gap_ext_adv_params *params,
|
||||
int8_t *selected_tx_power,
|
||||
@@ -913,6 +965,28 @@ int ble_gap_ext_adv_stop(uint8_t instance);
|
||||
int ble_gap_ext_adv_set_data(uint8_t instance, struct os_mbuf *data);
|
||||
int ble_gap_ext_adv_rsp_set_data(uint8_t instance, struct os_mbuf *data);
|
||||
int ble_gap_ext_adv_remove(uint8_t instance);
|
||||
|
||||
#if MYNEWT_VAL(BLE_PERIODIC_ADV)
|
||||
/* Periodic Advertising */
|
||||
int ble_gap_periodic_adv_configure(uint8_t instance, const struct ble_gap_periodic_adv_params *params);
|
||||
int ble_gap_periodic_adv_start(uint8_t instance);
|
||||
int ble_gap_periodic_adv_stop(uint8_t instance);
|
||||
int ble_gap_periodic_adv_set_data(uint8_t instance, struct os_mbuf *data);
|
||||
int ble_gap_periodic_adv_create_sync (uint8_t filter_policy,
|
||||
uint8_t adv_sid, uint8_t adv_add_type,
|
||||
const uint8_t *adv_addr, uint16_t skip,
|
||||
uint16_t sync_timeout);
|
||||
int ble_gap_periodic_adv_create_sync_cancel(void);
|
||||
int ble_gap_periodic_adv_terminate_sync(uint16_t sync_handle);
|
||||
int ble_gap_add_dev_to_periodic_adv_list(uint8_t adv_add_type, const uint8_t *adv_add,
|
||||
uint8_t adv_sid);
|
||||
int ble_gap_rem_dev_from_periodic_adv_list(uint8_t adv_addr_type,
|
||||
const uint8_t *adv_addr,
|
||||
uint8_t adv_sid);
|
||||
int ble_gap_clear_periodic_adv_list(void);
|
||||
int ble_gap_read_periodic_adv_list_size(uint8_t *per_adv_list_size);
|
||||
#endif
|
||||
|
||||
#endif
|
||||
|
||||
/**
|
||||
|
||||
+663
-24
@@ -74,10 +74,11 @@
|
||||
*/
|
||||
|
||||
/** GAP procedure op codes. */
|
||||
#define BLE_GAP_OP_NULL 0
|
||||
#define BLE_GAP_OP_M_DISC 1
|
||||
#define BLE_GAP_OP_M_CONN 2
|
||||
#define BLE_GAP_OP_S_ADV 1
|
||||
#define BLE_GAP_OP_NULL 0
|
||||
#define BLE_GAP_OP_M_DISC 1
|
||||
#define BLE_GAP_OP_M_CONN 2
|
||||
#define BLE_GAP_OP_S_ADV 1
|
||||
#define BLE_GAP_OP_S_PERIODIC_ADV 2
|
||||
|
||||
/**
|
||||
* If an attempt to cancel an active procedure fails, the attempt is retried
|
||||
@@ -128,6 +129,13 @@ struct ble_gap_master_state {
|
||||
uint8_t limited:1;
|
||||
} disc;
|
||||
};
|
||||
|
||||
#if MYNEWT_VAL(BLE_PERIODIC_ADV)
|
||||
/* Tells if create_sync was called without receiving sync
|
||||
* established event
|
||||
*/
|
||||
uint8_t pending_create_sync;
|
||||
#endif
|
||||
};
|
||||
static bssnz_t struct ble_gap_master_state ble_gap_master;
|
||||
|
||||
@@ -148,6 +156,10 @@ struct ble_gap_slave_state {
|
||||
unsigned int directed:1;
|
||||
unsigned int legacy_pdu:1;
|
||||
unsigned int rnd_addr_set:1;
|
||||
#if MYNEWT_VAL(BLE_PERIODIC_ADV)
|
||||
unsigned int periodic_configured:1;
|
||||
uint8_t periodic_op;
|
||||
#endif
|
||||
uint8_t rnd_addr[6];
|
||||
#else
|
||||
/* timer is used only with legacy advertising */
|
||||
@@ -176,7 +188,6 @@ struct ble_gap_snapshot {
|
||||
};
|
||||
|
||||
static SLIST_HEAD(ble_gap_hook_list, ble_gap_event_listener) ble_gap_event_listener_list;
|
||||
|
||||
static os_membuf_t ble_gap_update_entry_mem[
|
||||
OS_MEMPOOL_SIZE(MYNEWT_VAL(BLE_GAP_MAX_PENDING_CONN_PARAM_UPDATE),
|
||||
sizeof (struct ble_gap_update_entry))];
|
||||
@@ -433,22 +444,22 @@ int
|
||||
ble_gap_conn_find_by_addr(const ble_addr_t *addr,
|
||||
struct ble_gap_conn_desc *out_desc)
|
||||
{
|
||||
struct ble_hs_conn *conn;
|
||||
struct ble_hs_conn *conn;
|
||||
|
||||
ble_hs_lock();
|
||||
ble_hs_lock();
|
||||
|
||||
conn = ble_hs_conn_find_by_addr(addr);
|
||||
if (conn != NULL && out_desc != NULL) {
|
||||
ble_gap_fill_conn_desc(conn, out_desc);
|
||||
}
|
||||
conn = ble_hs_conn_find_by_addr(addr);
|
||||
if (conn != NULL && out_desc != NULL) {
|
||||
ble_gap_fill_conn_desc(conn, out_desc);
|
||||
}
|
||||
|
||||
ble_hs_unlock();
|
||||
ble_hs_unlock();
|
||||
|
||||
if (conn == NULL) {
|
||||
return BLE_HS_ENOTCONN;
|
||||
}
|
||||
if (conn == NULL) {
|
||||
return BLE_HS_ENOTCONN;
|
||||
}
|
||||
|
||||
return 0;
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int
|
||||
@@ -1283,6 +1294,111 @@ ble_gap_rx_adv_set_terminated(struct hci_le_adv_set_terminated *evt)
|
||||
}
|
||||
#endif
|
||||
|
||||
/* Periodic adv events */
|
||||
#if MYNEWT_VAL(BLE_EXT_ADV) && MYNEWT_VAL(BLE_PERIODIC_ADV)
|
||||
void
|
||||
ble_gap_rx_peroidic_adv_sync_estab(
|
||||
struct hci_le_subev_periodic_adv_sync_estab *evt)
|
||||
{
|
||||
struct ble_gap_event event;
|
||||
struct ble_gap_master_state state;
|
||||
struct ble_hs_periodic_sync * psync;
|
||||
|
||||
memset(&event, 0, sizeof event);
|
||||
|
||||
/* There must be memory for psync as the check was done when creating
|
||||
* sync
|
||||
*/
|
||||
psync = ble_hs_periodic_sync_alloc();
|
||||
BLE_HS_DBG_ASSERT(psync != NULL);
|
||||
|
||||
psync->sync_handle = evt->sync_handle;
|
||||
psync->adv_sid = evt->sid;
|
||||
psync->advertiser_addr_type = evt->adv_addr_type;
|
||||
|
||||
memcpy(psync->advertiser_addr.val, evt->adv_addr, 6);
|
||||
|
||||
psync->advertiser_phy = evt->adv_phy;
|
||||
psync->periodic_adv_itvl = evt->per_adv_ival;
|
||||
psync->advertiser_clock_accuracy = evt->adv_clk_accuracy;
|
||||
|
||||
ble_hs_lock();
|
||||
ble_hs_periodic_sync_insert(psync);
|
||||
ble_hs_unlock();
|
||||
|
||||
event.type = BLE_GAP_EVENT_PERIODIC_ADV_SYNC_ESTAB;
|
||||
event.periodic_adv_sync_estab.status = evt->status;
|
||||
event.periodic_adv_sync_estab.sync_handle = evt->sync_handle;
|
||||
event.periodic_adv_sync_estab.sid = evt->sid;
|
||||
event.periodic_adv_sync_estab.adv_addr_type = evt->adv_addr_type;
|
||||
|
||||
memcpy(event.periodic_adv_sync_estab.adv_addr, evt->adv_addr, 6);
|
||||
|
||||
event.periodic_adv_sync_estab.adv_phy = evt->adv_phy;
|
||||
event.periodic_adv_sync_estab.per_adv_ival = evt->per_adv_ival;
|
||||
event.periodic_adv_sync_estab.adv_clk_accuracy = evt->adv_clk_accuracy;
|
||||
|
||||
ble_gap_master.pending_create_sync = 0;
|
||||
|
||||
ble_gap_master_extract_state(&state, 0);
|
||||
if (ble_gap_has_client(&state)) {
|
||||
state.cb(&event, state.cb_arg);
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
ble_gap_rx_periodic_adv_rpt(struct hci_le_subev_periodic_adv_rpt *evt)
|
||||
{
|
||||
struct ble_gap_event event;
|
||||
struct ble_gap_master_state state;
|
||||
|
||||
memset(&event, 0, sizeof event);
|
||||
|
||||
event.type = BLE_GAP_EVENT_PERIODIC_DISC;
|
||||
event.periodic_disc.sync_handle = evt->sync_handle;
|
||||
event.periodic_disc.tx_power = evt->tx_power;
|
||||
event.periodic_disc.rssi = evt->rssi;
|
||||
event.periodic_disc.data_status = evt->data_status;
|
||||
event.periodic_disc.data_length = evt->data_length;
|
||||
event.periodic_disc.data = evt->data;
|
||||
|
||||
ble_gap_master_extract_state(&state, 0);
|
||||
if (ble_gap_has_client(&state)) {
|
||||
state.cb(&event, state.cb_arg);
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
ble_gap_rx_periodic_adv_sync_lost(
|
||||
struct hci_le_subev_periodic_adv_sync_lost *evt)
|
||||
{
|
||||
struct ble_gap_event event;
|
||||
struct ble_gap_master_state state;
|
||||
struct ble_hs_periodic_sync *psync;
|
||||
|
||||
memset(&event, 0, sizeof event);
|
||||
|
||||
event.type = BLE_GAP_EVENT_PERIODIC_ADV_SYNC_LOST;
|
||||
event.periodic_adv_sync_lost.sync_handle = evt->sync_handle;
|
||||
|
||||
ble_hs_lock();
|
||||
/* The handle must be in the list */
|
||||
psync = ble_hs_periodic_sync_find_assert(evt->sync_handle);
|
||||
|
||||
/* Remove the handle from the list */
|
||||
ble_hs_periodic_sync_remove(psync);
|
||||
|
||||
/* Free the memory occupied by psync as it is no longer needed */
|
||||
ble_hs_periodic_sync_free(psync);
|
||||
ble_hs_unlock();
|
||||
|
||||
ble_gap_master_extract_state(&state, 0);
|
||||
if (ble_gap_has_client(&state)) {
|
||||
state.cb(&event, state.cb_arg);
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
static int
|
||||
ble_gap_rd_rem_sup_feat_tx(uint16_t handle)
|
||||
{
|
||||
@@ -2509,7 +2625,7 @@ ble_gap_ext_adv_start(uint8_t instance, int duration, int max_events)
|
||||
if (ble_gap_slave[instance].rnd_addr_set) {
|
||||
break;
|
||||
}
|
||||
/* fall through */
|
||||
/* fall through */
|
||||
case BLE_OWN_ADDR_PUBLIC:
|
||||
case BLE_OWN_ADDR_RPA_PUBLIC_DEFAULT:
|
||||
default:
|
||||
@@ -2680,7 +2796,7 @@ ble_gap_ext_adv_set(uint8_t instance, uint16_t opcode, struct os_mbuf **data)
|
||||
opcode = BLE_HCI_OP(BLE_HCI_OGF_LE, opcode);
|
||||
|
||||
rc = ble_hs_hci_cmd_build_le_ext_adv_data(instance,
|
||||
BLE_HCI_LE_SET_EXT_ADV_DATA_OPER_COMPLETE,
|
||||
BLE_HCI_LE_SET_DATA_OPER_COMPLETE,
|
||||
0, *data, len, buf, sizeof(buf));
|
||||
if (rc) {
|
||||
return rc;
|
||||
@@ -2703,7 +2819,7 @@ ble_gap_ext_adv_set(uint8_t instance, uint16_t opcode, struct os_mbuf **data)
|
||||
/* complete data */
|
||||
if (len <= BLE_HCI_MAX_EXT_ADV_DATA_LEN) {
|
||||
rc = ble_hs_hci_cmd_build_le_ext_adv_data(instance,
|
||||
BLE_HCI_LE_SET_EXT_ADV_DATA_OPER_COMPLETE,
|
||||
BLE_HCI_LE_SET_DATA_OPER_COMPLETE,
|
||||
0, *data, len, buf,sizeof(buf));
|
||||
if (rc) {
|
||||
return rc;
|
||||
@@ -2717,7 +2833,7 @@ ble_gap_ext_adv_set(uint8_t instance, uint16_t opcode, struct os_mbuf **data)
|
||||
}
|
||||
|
||||
/* first fragment */
|
||||
op = BLE_HCI_LE_SET_EXT_ADV_DATA_OPER_FIRST;
|
||||
op = BLE_HCI_LE_SET_DATA_OPER_FIRST;
|
||||
|
||||
do {
|
||||
rc = ble_hs_hci_cmd_build_le_ext_adv_data(instance, op, 0, *data,
|
||||
@@ -2736,12 +2852,12 @@ ble_gap_ext_adv_set(uint8_t instance, uint16_t opcode, struct os_mbuf **data)
|
||||
}
|
||||
|
||||
len -= BLE_HCI_MAX_EXT_ADV_DATA_LEN;
|
||||
op = BLE_HCI_LE_SET_EXT_ADV_DATA_OPER_INT;
|
||||
op = BLE_HCI_LE_SET_DATA_OPER_INT;
|
||||
} while (len > BLE_HCI_MAX_EXT_ADV_DATA_LEN);
|
||||
|
||||
/* last fragment */
|
||||
rc = ble_hs_hci_cmd_build_le_ext_adv_data(instance,
|
||||
BLE_HCI_LE_SET_EXT_ADV_DATA_OPER_LAST,
|
||||
BLE_HCI_LE_SET_DATA_OPER_LAST,
|
||||
0, *data, len, buf, sizeof(buf));
|
||||
if (rc) {
|
||||
return rc;
|
||||
@@ -2891,6 +3007,529 @@ ble_gap_ext_adv_remove(uint8_t instance)
|
||||
return 0;
|
||||
}
|
||||
|
||||
#if MYNEWT_VAL(BLE_PERIODIC_ADV)
|
||||
static int
|
||||
ble_gap_periodic_adv_params_tx(uint8_t instance,
|
||||
const struct ble_gap_periodic_adv_params *params)
|
||||
|
||||
{
|
||||
struct hci_periodic_adv_params hci_adv_params;
|
||||
uint8_t buf[BLE_HCI_LE_SET_PERIODIC_ADV_PARAMS_LEN];
|
||||
int rc;
|
||||
|
||||
memset(&hci_adv_params, 0, sizeof(hci_adv_params));
|
||||
|
||||
if (params->include_tx_power) {
|
||||
hci_adv_params.properties |= BLE_HCI_LE_SET_PERIODIC_ADV_PROP_INC_TX_PWR;
|
||||
}
|
||||
|
||||
/* Fill optional fields if application did not specify them. */
|
||||
if (params->itvl_min == 0 && params->itvl_max == 0) {
|
||||
hci_adv_params.min_interval = 30 / 1.25; //30 ms
|
||||
hci_adv_params.max_interval = 60 / 1.25; //150 ms
|
||||
|
||||
} else {
|
||||
hci_adv_params.min_interval = params->itvl_min;
|
||||
hci_adv_params.max_interval = params->itvl_max;
|
||||
}
|
||||
|
||||
rc = ble_hs_hci_cmd_build_le_periodic_adv_params(instance, &hci_adv_params, buf,
|
||||
sizeof(buf));
|
||||
if (rc != 0) {
|
||||
return rc;
|
||||
}
|
||||
|
||||
rc = ble_hs_hci_cmd_tx_empty_ack(
|
||||
BLE_HCI_OP(BLE_HCI_OGF_LE, BLE_HCI_OCF_LE_SET_PERIODIC_ADV_PARAMS), buf,
|
||||
sizeof(buf));
|
||||
|
||||
if (rc != 0) {
|
||||
return rc;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int
|
||||
ble_gap_periodic_adv_params_validate(
|
||||
const struct ble_gap_periodic_adv_params *params)
|
||||
{
|
||||
if (!params) {
|
||||
return BLE_HS_EINVAL;
|
||||
}
|
||||
|
||||
if (params->itvl_min > 0xffff || params->itvl_min < 6) {
|
||||
return BLE_HS_EINVAL;
|
||||
}
|
||||
if (params->itvl_max > 0xffff || params->itvl_max < 6) {
|
||||
return BLE_HS_EINVAL;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
int
|
||||
ble_gap_periodic_adv_configure(uint8_t instance,
|
||||
const struct ble_gap_periodic_adv_params *params)
|
||||
{
|
||||
int rc;
|
||||
|
||||
if (instance >= BLE_ADV_INSTANCES) {
|
||||
return BLE_HS_EINVAL;
|
||||
}
|
||||
|
||||
rc = ble_gap_periodic_adv_params_validate(params);
|
||||
if (rc) {
|
||||
return rc;
|
||||
}
|
||||
|
||||
ble_hs_lock();
|
||||
|
||||
/* The corresponding extended advertising instance should be configured */
|
||||
if (!ble_gap_slave[instance].configured) {
|
||||
ble_hs_unlock();
|
||||
return ENOMEM;
|
||||
}
|
||||
|
||||
/* Periodic advertising shall not be configured while it is already
|
||||
* running.
|
||||
* Bluetooth Core Specification, Section 7.8.61
|
||||
*/
|
||||
if (ble_gap_slave[instance].periodic_op == BLE_GAP_OP_S_PERIODIC_ADV) {
|
||||
ble_hs_unlock();
|
||||
return BLE_HS_EINVAL;
|
||||
}
|
||||
|
||||
rc = ble_gap_periodic_adv_params_tx(instance, params);
|
||||
if (rc) {
|
||||
ble_hs_unlock();
|
||||
return rc;
|
||||
}
|
||||
|
||||
ble_gap_slave[instance].periodic_configured = 1;
|
||||
|
||||
ble_hs_unlock();
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int
|
||||
ble_gap_periodic_adv_start(uint8_t instance)
|
||||
{
|
||||
uint8_t buf[BLE_HCI_LE_SET_PERIODIC_ADV_ENABLE_LEN];
|
||||
uint16_t opcode;
|
||||
int rc;
|
||||
|
||||
if (instance >= BLE_ADV_INSTANCES) {
|
||||
return BLE_HS_EINVAL;
|
||||
}
|
||||
|
||||
ble_hs_lock();
|
||||
|
||||
/* Periodic advertising cannot start unless it is configured before */
|
||||
if (!ble_gap_slave[instance].periodic_configured) {
|
||||
ble_hs_unlock();
|
||||
return BLE_HS_EINVAL;
|
||||
}
|
||||
|
||||
opcode = BLE_HCI_OP(BLE_HCI_OGF_LE,
|
||||
BLE_HCI_OCF_LE_SET_PERIODIC_ADV_ENABLE);
|
||||
rc = ble_hs_hci_cmd_build_le_periodic_adv_enable(1, instance, buf,
|
||||
sizeof(buf));
|
||||
if (rc != 0) {
|
||||
ble_hs_unlock();
|
||||
return rc;
|
||||
}
|
||||
|
||||
rc = ble_hs_hci_cmd_tx_empty_ack(opcode, buf, sizeof(buf));
|
||||
if (rc != 0) {
|
||||
ble_hs_unlock();
|
||||
return rc;
|
||||
}
|
||||
|
||||
ble_gap_slave[instance].periodic_op = BLE_GAP_OP_S_PERIODIC_ADV;
|
||||
|
||||
ble_hs_unlock();
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int
|
||||
ble_gap_periodic_adv_set(uint8_t instance, uint16_t opcode,
|
||||
struct os_mbuf **data)
|
||||
{
|
||||
/* In that case we always fit all data in single HCI command */
|
||||
#if MYNEWT_VAL(BLE_EXT_ADV_MAX_SIZE) <= BLE_HCI_MAX_PERIODIC_ADV_DATA_LEN
|
||||
|
||||
static uint8_t buf[BLE_HCI_SET_PERIODIC_ADV_DATA_HDR_LEN +
|
||||
MYNEWT_VAL(BLE_EXT_ADV_MAX_SIZE)];
|
||||
uint16_t len = OS_MBUF_PKTLEN(*data);
|
||||
int rc;
|
||||
|
||||
opcode = BLE_HCI_OP(BLE_HCI_OGF_LE, opcode);
|
||||
|
||||
rc = ble_hs_hci_cmd_build_le_periodic_adv_data(
|
||||
instance,
|
||||
BLE_HCI_LE_SET_DATA_OPER_COMPLETE,
|
||||
*data, len,
|
||||
buf, sizeof(buf));
|
||||
|
||||
if (rc) {
|
||||
return rc;
|
||||
}
|
||||
|
||||
os_mbuf_adj(*data, MYNEWT_VAL(BLE_EXT_ADV_MAX_SIZE));
|
||||
*data = os_mbuf_trim_front(*data);
|
||||
|
||||
return ble_hs_hci_cmd_tx_empty_ack(opcode, buf,
|
||||
BLE_HCI_SET_PERIODIC_ADV_DATA_HDR_LEN + len);
|
||||
#else
|
||||
static uint8_t buf[BLE_HCI_SET_PERIODIC_ADV_DATA_HDR_LEN +
|
||||
BLE_HCI_MAX_PERIODIC_ADV_DATA_LEN];
|
||||
uint16_t len = OS_MBUF_PKTLEN(*data);
|
||||
uint8_t op;
|
||||
int rc;
|
||||
|
||||
opcode = BLE_HCI_OP(BLE_HCI_OGF_LE, opcode);
|
||||
|
||||
/* Complete data */
|
||||
if (len <= BLE_HCI_MAX_PERIODIC_ADV_DATA_LEN) {
|
||||
rc = ble_hs_hci_cmd_build_le_periodic_adv_data(instance,
|
||||
BLE_HCI_LE_SET_DATA_OPER_COMPLETE, *data, len, buf,
|
||||
sizeof(buf));
|
||||
if (rc) {
|
||||
return rc;
|
||||
}
|
||||
|
||||
os_mbuf_adj(*data, len);
|
||||
*data = os_mbuf_trim_front(*data);
|
||||
|
||||
return ble_hs_hci_cmd_tx_empty_ack(opcode, buf,
|
||||
BLE_HCI_SET_PERIODIC_ADV_DATA_HDR_LEN + len);
|
||||
}
|
||||
|
||||
/* If the periodic advertising is already enabled, the periodic advertising
|
||||
* the op code shall be nothing but 0x03
|
||||
* Bluetooth Core Specification, section 7.8.62
|
||||
*/
|
||||
if (ble_gap_slave[instance].periodic_op == BLE_GAP_OP_S_PERIODIC_ADV) {
|
||||
return BLE_HS_EINVAL;
|
||||
}
|
||||
|
||||
/* First fragment */
|
||||
op = BLE_HCI_LE_SET_DATA_OPER_FIRST;
|
||||
|
||||
do{
|
||||
rc = ble_hs_hci_cmd_build_le_periodic_adv_data(instance, op, *data,
|
||||
BLE_HCI_MAX_PERIODIC_ADV_DATA_LEN, buf, sizeof(buf));
|
||||
if (rc) {
|
||||
return rc;
|
||||
}
|
||||
|
||||
os_mbuf_adj(*data, BLE_HCI_MAX_PERIODIC_ADV_DATA_LEN);
|
||||
*data = os_mbuf_trim_front(*data);
|
||||
|
||||
rc = ble_hs_hci_cmd_tx_empty_ack(opcode, buf, sizeof(buf));
|
||||
if (rc) {
|
||||
return rc;
|
||||
}
|
||||
|
||||
len -= BLE_HCI_MAX_PERIODIC_ADV_DATA_LEN;
|
||||
op = BLE_HCI_LE_SET_DATA_OPER_INT;
|
||||
} while (len > BLE_HCI_MAX_PERIODIC_ADV_DATA_LEN);
|
||||
|
||||
/* Last fragment */
|
||||
rc = ble_hs_hci_cmd_build_le_periodic_adv_data(
|
||||
instance,
|
||||
BLE_HCI_LE_SET_DATA_OPER_LAST,
|
||||
*data, len, buf, sizeof(buf));
|
||||
if (rc) {
|
||||
return rc;
|
||||
}
|
||||
|
||||
os_mbuf_adj(*data, len);
|
||||
*data = os_mbuf_trim_front(*data);
|
||||
|
||||
return ble_hs_hci_cmd_tx_empty_ack(opcode, buf,
|
||||
BLE_HCI_SET_PERIODIC_ADV_DATA_HDR_LEN + len);
|
||||
#endif
|
||||
}
|
||||
|
||||
static int
|
||||
ble_gap_periodic_adv_set_data_validate(uint8_t instance,
|
||||
struct os_mbuf *data)
|
||||
{
|
||||
/* The corresponding extended advertising instance should be configured */
|
||||
if (!ble_gap_slave[instance].configured) {
|
||||
return BLE_HS_EINVAL;
|
||||
}
|
||||
|
||||
if (ble_gap_slave[instance].legacy_pdu) {
|
||||
return BLE_HS_EINVAL;
|
||||
}
|
||||
|
||||
/* One more check states that if the periodic advertising is already
|
||||
* enabled, the operation shall be 0x03 (Complete).
|
||||
* This check is handled during sending the data to the controller, as the
|
||||
* length checks are already checked there, so this saves duplicate code
|
||||
*/
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int
|
||||
ble_gap_periodic_adv_set_data(uint8_t instance, struct os_mbuf *data)
|
||||
{
|
||||
int rc;
|
||||
if (instance >= BLE_ADV_INSTANCES) {
|
||||
rc = BLE_HS_EINVAL;
|
||||
goto done;
|
||||
}
|
||||
|
||||
ble_hs_lock();
|
||||
|
||||
rc = ble_gap_periodic_adv_set_data_validate(instance, data);
|
||||
if (rc != 0) {
|
||||
ble_hs_unlock();
|
||||
goto done;
|
||||
}
|
||||
|
||||
rc = ble_gap_periodic_adv_set(
|
||||
instance,
|
||||
BLE_HCI_OCF_LE_SET_PERIODIC_ADV_DATA,
|
||||
&data);
|
||||
|
||||
ble_hs_unlock();
|
||||
|
||||
done:
|
||||
os_mbuf_free_chain(data);
|
||||
return rc;
|
||||
}
|
||||
|
||||
static int
|
||||
ble_gap_periodic_adv_stop_no_lock(uint8_t instance)
|
||||
{
|
||||
uint8_t buf[BLE_HCI_LE_SET_PERIODIC_ADV_ENABLE_LEN];
|
||||
uint16_t opcode;
|
||||
int rc;
|
||||
|
||||
opcode = BLE_HCI_OP(BLE_HCI_OGF_LE, BLE_HCI_OCF_LE_SET_PERIODIC_ADV_ENABLE);
|
||||
|
||||
rc = ble_hs_hci_cmd_build_le_periodic_adv_enable(0, instance, buf, sizeof(buf));
|
||||
if (rc != 0) {
|
||||
return rc;
|
||||
}
|
||||
|
||||
rc = ble_hs_hci_cmd_tx_empty_ack(opcode, buf, sizeof(buf));
|
||||
if (rc != 0) {
|
||||
return rc;
|
||||
}
|
||||
|
||||
ble_gap_slave[instance].periodic_op = BLE_GAP_OP_NULL;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int
|
||||
ble_gap_periodic_adv_stop(uint8_t instance)
|
||||
{
|
||||
int rc;
|
||||
|
||||
if (instance >= BLE_ADV_INSTANCES) {
|
||||
return BLE_HS_EINVAL;
|
||||
}
|
||||
|
||||
ble_hs_lock();
|
||||
rc = ble_gap_periodic_adv_stop_no_lock(instance);
|
||||
ble_hs_unlock();
|
||||
|
||||
return rc;
|
||||
}
|
||||
|
||||
int
|
||||
ble_gap_periodic_adv_create_sync(uint8_t filter_policy, uint8_t adv_sid,
|
||||
uint8_t adv_addr_type, const uint8_t *adv_addr, uint16_t skip,
|
||||
uint16_t sync_timeout)
|
||||
{
|
||||
uint8_t buf[BLE_HCI_LE_PERIODIC_ADV_CREATE_SYNC_LEN];
|
||||
uint16_t opcode;
|
||||
int rc = 0;
|
||||
|
||||
if (!ble_hs_periodic_sync_can_alloc()) {
|
||||
return BLE_HS_ENOMEM;
|
||||
}
|
||||
opcode = BLE_HCI_OP(BLE_HCI_OGF_LE,
|
||||
BLE_HCI_OCF_LE_PERIODIC_ADV_CREATE_SYNC);
|
||||
|
||||
/* No sync can be created if another sync is still pending */
|
||||
if (ble_gap_master.pending_create_sync) {
|
||||
return BLE_HS_EINVAL;
|
||||
}
|
||||
|
||||
rc = ble_hs_hci_cmd_build_le_periodic_adv_create_sync(filter_policy,
|
||||
adv_sid,
|
||||
adv_addr_type,
|
||||
adv_addr,
|
||||
skip, sync_timeout,
|
||||
buf, sizeof(buf));
|
||||
if (rc != 0) {
|
||||
return rc;
|
||||
}
|
||||
|
||||
/* This shall be reset upon receiving sync_established event,
|
||||
* or if the sync is cancelled before receiving that event.
|
||||
*/
|
||||
ble_gap_master.pending_create_sync = 1;
|
||||
|
||||
rc = ble_hs_hci_cmd_tx_empty_ack(opcode, buf, sizeof(buf));
|
||||
|
||||
return rc;
|
||||
}
|
||||
|
||||
int
|
||||
ble_gap_periodic_adv_create_sync_cancel(void)
|
||||
{
|
||||
uint16_t opcode;
|
||||
int rc = 0;
|
||||
|
||||
if (!ble_gap_master.pending_create_sync) {
|
||||
return BLE_HS_EINVAL;
|
||||
}
|
||||
|
||||
opcode = BLE_HCI_OP(BLE_HCI_OGF_LE,
|
||||
BLE_HCI_OCF_LE_PERIODIC_ADV_CREATE_SYNC_CANCEL);
|
||||
|
||||
rc = ble_hs_hci_cmd_tx_empty_ack(opcode, NULL, 0);
|
||||
|
||||
if (!rc) {
|
||||
ble_gap_master.pending_create_sync = 0;
|
||||
}
|
||||
return rc;
|
||||
}
|
||||
|
||||
int
|
||||
ble_gap_periodic_adv_terminate_sync(uint16_t sync_handle)
|
||||
{
|
||||
uint8_t buf[BLE_HCI_LE_PERIODIC_ADV_TERM_SYNC_LEN];
|
||||
uint16_t opcode;
|
||||
struct ble_hs_periodic_sync *psync;
|
||||
int rc = 0;
|
||||
|
||||
if (ble_gap_master.pending_create_sync) {
|
||||
return BLE_HS_EINVAL;
|
||||
}
|
||||
|
||||
ble_hs_lock();
|
||||
/* The handle must be in the list. If it doesn't exist, it means
|
||||
* that the sync may have been lost at the same moment in which
|
||||
* the app wants to terminate that sync handle */
|
||||
psync = ble_hs_periodic_sync_find(sync_handle);
|
||||
if (!psync) {
|
||||
/* Sync already terminated. TODO: Not sure what error code
|
||||
* describes this scnario the best */
|
||||
rc = BLE_HS_EALREADY;
|
||||
goto done;
|
||||
}
|
||||
|
||||
/* Remove the handle from the list */
|
||||
ble_hs_periodic_sync_remove(psync);
|
||||
|
||||
/* Free the memory occupied by psync as it is no longer needed */
|
||||
ble_hs_periodic_sync_free(psync);
|
||||
ble_hs_unlock();
|
||||
|
||||
opcode = BLE_HCI_OP(BLE_HCI_OGF_LE, BLE_HCI_OCF_LE_PERIODIC_ADV_TERM_SYNC);
|
||||
|
||||
rc = ble_hs_hci_cmd_build_le_periodic_adv_terminate_sync(sync_handle,
|
||||
buf, sizeof(buf));
|
||||
if (rc != 0) {
|
||||
return rc;
|
||||
}
|
||||
|
||||
rc = ble_hs_hci_cmd_tx_empty_ack(opcode, buf, sizeof(buf));
|
||||
|
||||
done:
|
||||
return rc;
|
||||
}
|
||||
|
||||
int
|
||||
ble_gap_add_dev_to_periodic_adv_list(uint8_t adv_addr_type,
|
||||
const uint8_t *adv_addr, uint8_t adv_sid)
|
||||
{
|
||||
uint8_t buf[BLE_HCI_LE_ADD_DEV_TO_PERIODIC_ADV_LIST_LEN];
|
||||
uint16_t opcode;
|
||||
int rc = 0;
|
||||
|
||||
opcode = BLE_HCI_OP(BLE_HCI_OGF_LE, BLE_HCI_OCF_LE_ADD_DEV_TO_PERIODIC_ADV_LIST);
|
||||
|
||||
rc = ble_hs_hci_cmd_build_le_add_dev_to_periodic_adv_list(adv_addr_type,
|
||||
adv_addr, adv_sid, buf, sizeof(buf));
|
||||
if (rc != 0) {
|
||||
return rc;
|
||||
}
|
||||
|
||||
rc = ble_hs_hci_cmd_tx_empty_ack(opcode, buf, sizeof(buf));
|
||||
|
||||
return rc;
|
||||
}
|
||||
|
||||
int
|
||||
ble_gap_rem_dev_from_periodic_adv_list(uint8_t adv_addr_type,
|
||||
const uint8_t *adv_addr, uint8_t adv_sid)
|
||||
{
|
||||
uint8_t buf[BLE_HCI_LE_REM_DEV_FROM_PERIODIC_ADV_LIST_LEN];
|
||||
uint16_t opcode;
|
||||
int rc = 0;
|
||||
|
||||
opcode = BLE_HCI_OP(BLE_HCI_OGF_LE,
|
||||
BLE_HCI_OCF_LE_REM_DEV_FROM_PERIODIC_ADV_LIST);
|
||||
|
||||
rc = ble_hs_hci_cmd_build_le_rem_dev_from_periodic_adv_list(adv_addr_type,
|
||||
adv_addr, adv_sid, buf, sizeof(buf));
|
||||
if (rc != 0) {
|
||||
return rc;
|
||||
}
|
||||
|
||||
rc = ble_hs_hci_cmd_tx_empty_ack(opcode, buf, sizeof(buf));
|
||||
|
||||
return rc;
|
||||
}
|
||||
|
||||
int
|
||||
ble_gap_clear_periodic_adv_list(void)
|
||||
{
|
||||
uint16_t opcode;
|
||||
int rc = 0;
|
||||
|
||||
opcode = BLE_HCI_OP(BLE_HCI_OGF_LE, BLE_HCI_OCF_LE_CLEAR_PERIODIC_ADV_LIST);
|
||||
|
||||
rc = ble_hs_hci_cmd_tx_empty_ack(opcode, NULL, 0);
|
||||
|
||||
return rc;
|
||||
}
|
||||
|
||||
int
|
||||
ble_gap_read_periodic_adv_list_size(uint8_t *per_adv_list_size)
|
||||
{
|
||||
uint8_t rspbuf[1];
|
||||
uint8_t rsplen;
|
||||
uint16_t opcode;
|
||||
int rc = 0;
|
||||
|
||||
opcode = BLE_HCI_OP(BLE_HCI_OGF_LE, BLE_HCI_OCF_LE_RD_PERIODIC_ADV_LIST_SIZE);
|
||||
|
||||
rc = ble_hs_hci_cmd_tx(opcode, NULL, 0, rspbuf, sizeof(rspbuf), &rsplen);
|
||||
if (rc != 0) {
|
||||
return rc;
|
||||
}
|
||||
|
||||
if (rsplen != sizeof(rspbuf)) {
|
||||
return BLE_HS_ECONTROLLER;
|
||||
}
|
||||
|
||||
*per_adv_list_size = rspbuf[0];
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
/*****************************************************************************
|
||||
@@ -2957,7 +3596,7 @@ ble_gap_ext_disc_enable_tx(uint8_t enable, uint8_t filter_duplicates,
|
||||
buf, sizeof(buf));
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif
|
||||
#if NIMBLE_BLE_SCAN
|
||||
#if !MYNEWT_VAL(BLE_EXT_ADV)
|
||||
static int
|
||||
@@ -4702,7 +5341,7 @@ ble_gap_preempt_done(void)
|
||||
|
||||
disc_preempted = 0;
|
||||
|
||||
/* protects slaves from accessing by multiple threads */
|
||||
/* Protects slaves from accessing by multiple threads */
|
||||
ble_npl_mutex_pend(&preempt_done_mutex, 0xFFFFFFFF);
|
||||
memset(slaves, 0, sizeof(slaves));
|
||||
|
||||
|
||||
@@ -82,6 +82,11 @@ void ble_gap_rx_le_scan_timeout(void);
|
||||
#if MYNEWT_VAL(BLE_EXT_ADV)
|
||||
void ble_gap_rx_ext_adv_report(struct ble_gap_ext_disc_desc *desc);
|
||||
void ble_gap_rx_adv_set_terminated(struct hci_le_adv_set_terminated *evt);
|
||||
#if MYNEWT_VAL(BLE_PERIODIC_ADV)
|
||||
void ble_gap_rx_peroidic_adv_sync_estab(struct hci_le_subev_periodic_adv_sync_estab *evt);
|
||||
void ble_gap_rx_periodic_adv_rpt(struct hci_le_subev_periodic_adv_rpt *evt);
|
||||
void ble_gap_rx_periodic_adv_sync_lost(struct hci_le_subev_periodic_adv_sync_lost *evt);
|
||||
#endif
|
||||
#endif
|
||||
void ble_gap_rx_adv_report(struct ble_gap_disc_desc *desc);
|
||||
void ble_gap_rx_rd_rem_sup_feat_complete(struct hci_le_rd_rem_supp_feat_complete *evt);
|
||||
|
||||
@@ -744,6 +744,9 @@ ble_hs_init(void)
|
||||
rc = ble_hs_conn_init();
|
||||
SYSINIT_PANIC_ASSERT(rc == 0);
|
||||
|
||||
rc = ble_hs_periodic_sync_init();
|
||||
SYSINIT_PANIC_ASSERT(rc == 0);
|
||||
|
||||
rc = ble_l2cap_init();
|
||||
SYSINIT_PANIC_ASSERT(rc == 0);
|
||||
|
||||
|
||||
@@ -224,10 +224,10 @@ ble_hs_dbg_le_event_disp(uint8_t subev, uint8_t len, uint8_t *evdata)
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
case BLE_HCI_LE_SUBEV_PER_ADV_SYNC_ESTAB:
|
||||
#if MYNEWT_VAL(BLE_PERIODIC_ADV)
|
||||
case BLE_HCI_LE_SUBEV_PERIODIC_ADV_SYNC_ESTAB:
|
||||
{
|
||||
struct hci_le_subev_per_adv_sync_estab *data = (void *) evdata;
|
||||
struct hci_le_subev_periodic_adv_sync_estab *data = (void *) evdata;
|
||||
|
||||
if (len != sizeof(*data)) {
|
||||
BLE_HS_LOG(DEBUG, "Corrupted LE Periodic Advertising Sync "
|
||||
@@ -241,9 +241,9 @@ ble_hs_dbg_le_event_disp(uint8_t subev, uint8_t len, uint8_t *evdata)
|
||||
break;
|
||||
}
|
||||
|
||||
case BLE_HCI_LE_SUBEV_PER_ADV_RPT:
|
||||
case BLE_HCI_LE_SUBEV_PERIODIC_ADV_RPT:
|
||||
{
|
||||
struct hci_le_subev_per_adv_rpt *data = (void *) evdata;
|
||||
struct hci_le_subev_periodic_adv_rpt *data = (void *) evdata;
|
||||
|
||||
if (len < sizeof(*data) || len != sizeof(*data) + data->data_length) {
|
||||
BLE_HS_LOG(DEBUG, "Corrupted LE Periodic Advertising Report "
|
||||
@@ -258,9 +258,9 @@ ble_hs_dbg_le_event_disp(uint8_t subev, uint8_t len, uint8_t *evdata)
|
||||
break;
|
||||
}
|
||||
|
||||
case BLE_HCI_LE_SUBEV_PER_ADV_SYNC_LOST:
|
||||
case BLE_HCI_LE_SUBEV_PERIODIC_ADV_SYNC_LOST:
|
||||
{
|
||||
struct hci_le_subev_per_adv_sync_lost *data = (void *) evdata;
|
||||
struct hci_le_subev_periodic_adv_sync_lost *data = (void *) evdata;
|
||||
|
||||
if (len != sizeof(*data)) {
|
||||
BLE_HS_LOG(DEBUG, "Corrupted LE Periodic Advertising Sync Lost "
|
||||
@@ -272,6 +272,7 @@ ble_hs_dbg_le_event_disp(uint8_t subev, uint8_t len, uint8_t *evdata)
|
||||
"len=%u handle=0x%04x", len, le16toh(data->sync_handle));
|
||||
break;
|
||||
}
|
||||
#endif
|
||||
|
||||
case BLE_HCI_LE_SUBEV_SCAN_TIMEOUT:
|
||||
if (len) {
|
||||
|
||||
@@ -1605,6 +1605,164 @@ ble_hs_hci_cmd_build_le_ext_adv_remove(uint8_t handle,
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
#if MYNEWT_VAL(BLE_PERIODIC_ADV)
|
||||
int
|
||||
ble_hs_hci_cmd_build_le_periodic_adv_params(uint8_t handle,
|
||||
const struct hci_periodic_adv_params *params,
|
||||
uint8_t *cmd, int cmd_len)
|
||||
{
|
||||
BLE_HS_DBG_ASSERT(cmd_len >= BLE_HCI_LE_SET_PERIODIC_ADV_PARAMS_LEN);
|
||||
|
||||
if (handle > 0xEF){
|
||||
return BLE_ERR_INV_HCI_CMD_PARMS;
|
||||
}
|
||||
if (params->max_interval > 0xFFFF || params->max_interval < 6){
|
||||
return BLE_ERR_INV_HCI_CMD_PARMS;
|
||||
}
|
||||
if (params->min_interval > 0xFFFF || params->min_interval < 6){
|
||||
return BLE_ERR_INV_HCI_CMD_PARMS;
|
||||
}
|
||||
|
||||
cmd[0] = handle;
|
||||
|
||||
put_le16(&cmd[1], params->min_interval);
|
||||
put_le16(&cmd[3], params->max_interval);
|
||||
put_le16(&cmd[5], params->properties);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int
|
||||
ble_hs_hci_cmd_build_le_periodic_adv_enable(uint8_t enable,
|
||||
uint8_t handle,
|
||||
uint8_t *cmd, int cmd_len)
|
||||
{
|
||||
BLE_HS_DBG_ASSERT(cmd_len >= BLE_HCI_LE_SET_PERIODIC_ADV_ENABLE_LEN);
|
||||
|
||||
if (enable > 1){
|
||||
return BLE_ERR_INV_HCI_CMD_PARMS;
|
||||
}
|
||||
|
||||
cmd[0] = enable;
|
||||
cmd[1] = handle;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int
|
||||
ble_hs_hci_cmd_build_le_periodic_adv_data(uint8_t handle,
|
||||
uint8_t operation,
|
||||
struct os_mbuf *data,
|
||||
uint8_t data_len,
|
||||
uint8_t *cmd, int cmd_len)
|
||||
{
|
||||
BLE_HS_DBG_ASSERT(cmd_len >= 3 + data_len);
|
||||
|
||||
if (!data){
|
||||
return BLE_ERR_INV_HCI_CMD_PARMS;
|
||||
}
|
||||
if (!data->om_data){
|
||||
return BLE_ERR_INV_HCI_CMD_PARMS;
|
||||
}
|
||||
if (handle > 0xEF){
|
||||
return BLE_ERR_INV_HCI_CMD_PARMS;
|
||||
}
|
||||
|
||||
cmd[0] = handle;
|
||||
cmd[1] = operation;
|
||||
cmd[2] = data_len;
|
||||
os_mbuf_copydata(data, 0, data_len, cmd + 3);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int
|
||||
ble_hs_hci_cmd_build_le_periodic_adv_create_sync(uint8_t filter_policy,
|
||||
uint8_t adv_sid,
|
||||
uint8_t adv_add_type,
|
||||
const uint8_t *adv_addr,
|
||||
uint16_t skip,
|
||||
uint16_t sync_timeout,
|
||||
uint8_t *cmd, int cmd_len)
|
||||
{
|
||||
BLE_HS_DBG_ASSERT(cmd_len >= BLE_HCI_LE_PERIODIC_ADV_CREATE_SYNC_LEN);
|
||||
|
||||
if (filter_policy > 1 || adv_add_type > 1){
|
||||
return BLE_ERR_INV_HCI_CMD_PARMS;
|
||||
}
|
||||
if (adv_sid > 0x0f){
|
||||
return BLE_ERR_INV_HCI_CMD_PARMS;
|
||||
}
|
||||
if (skip > 0x1f3 || sync_timeout > 0x4000 || sync_timeout < 0x0A){
|
||||
return BLE_ERR_INV_HCI_CMD_PARMS;
|
||||
}
|
||||
cmd[0] = filter_policy;
|
||||
cmd[1] = adv_sid;
|
||||
cmd[2] = adv_add_type;
|
||||
memcpy(&cmd[3], adv_addr, 6);
|
||||
put_le16(&cmd[9], skip);
|
||||
put_le16(&cmd[11], sync_timeout);
|
||||
cmd[13] = 0x00;
|
||||
return 0;
|
||||
}
|
||||
|
||||
int
|
||||
ble_hs_hci_cmd_build_le_periodic_adv_terminate_sync(uint16_t sync_handle,
|
||||
uint8_t *cmd, int cmd_len)
|
||||
{
|
||||
BLE_HS_DBG_ASSERT(cmd_len >= BLE_HCI_LE_PERIODIC_ADV_TERM_SYNC_LEN);
|
||||
|
||||
if (sync_handle > 0xEF){
|
||||
return BLE_ERR_INV_HCI_CMD_PARMS;
|
||||
}
|
||||
|
||||
cmd[0] = sync_handle;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int
|
||||
ble_hs_hci_cmd_build_le_add_dev_to_periodic_adv_list(
|
||||
uint8_t adv_add_type,
|
||||
const uint8_t *adv_addr,
|
||||
uint8_t adv_sid,
|
||||
uint8_t *cmd, int cmd_len)
|
||||
{
|
||||
BLE_HS_DBG_ASSERT(cmd_len >= BLE_HCI_LE_ADD_DEV_TO_PERIODIC_ADV_LIST_LEN);
|
||||
|
||||
if (adv_add_type > 1 || adv_sid > 0x0f){
|
||||
return BLE_ERR_INV_HCI_CMD_PARMS;
|
||||
}
|
||||
|
||||
cmd[0] = adv_add_type;
|
||||
memcpy(&cmd[1], adv_addr, 6);
|
||||
cmd[7] = adv_sid;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int
|
||||
ble_hs_hci_cmd_build_le_rem_dev_from_periodic_adv_list(
|
||||
uint8_t adv_add_type,
|
||||
const uint8_t *adv_addr,
|
||||
uint8_t adv_sid,
|
||||
uint8_t *cmd, int cmd_len)
|
||||
{
|
||||
BLE_HS_DBG_ASSERT(cmd_len >= BLE_HCI_LE_REM_DEV_FROM_PERIODIC_ADV_LIST_LEN);
|
||||
|
||||
if (adv_add_type > 1 || adv_sid > 0x0f){
|
||||
return BLE_ERR_INV_HCI_CMD_PARMS;
|
||||
}
|
||||
|
||||
cmd[0] = adv_add_type;
|
||||
memcpy(&cmd[1], adv_addr, 6);
|
||||
cmd[7] = adv_sid;
|
||||
|
||||
return 0;
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif
|
||||
|
||||
static int
|
||||
|
||||
@@ -51,7 +51,9 @@ static ble_hs_hci_evt_le_fn ble_hs_hci_evt_le_ext_adv_rpt;
|
||||
static ble_hs_hci_evt_le_fn ble_hs_hci_evt_le_rd_rem_used_feat_complete;
|
||||
static ble_hs_hci_evt_le_fn ble_hs_hci_evt_le_scan_timeout;
|
||||
static ble_hs_hci_evt_le_fn ble_hs_hci_evt_le_adv_set_terminated;
|
||||
|
||||
static ble_hs_hci_evt_le_fn ble_hs_hci_evt_le_periodic_adv_sync_estab;
|
||||
static ble_hs_hci_evt_le_fn ble_hs_hci_evt_le_periodic_adv_rpt;
|
||||
static ble_hs_hci_evt_le_fn ble_hs_hci_evt_le_periodic_adv_sync_lost;
|
||||
/* Statistics */
|
||||
struct host_hci_stats
|
||||
{
|
||||
@@ -100,6 +102,11 @@ static const struct ble_hs_hci_evt_le_dispatch_entry
|
||||
{ BLE_HCI_LE_SUBEV_PHY_UPDATE_COMPLETE,
|
||||
ble_hs_hci_evt_le_phy_update_complete },
|
||||
{ BLE_HCI_LE_SUBEV_EXT_ADV_RPT, ble_hs_hci_evt_le_ext_adv_rpt },
|
||||
{ BLE_HCI_LE_SUBEV_PERIODIC_ADV_SYNC_ESTAB,
|
||||
ble_hs_hci_evt_le_periodic_adv_sync_estab},
|
||||
{ BLE_HCI_LE_SUBEV_PERIODIC_ADV_RPT, ble_hs_hci_evt_le_periodic_adv_rpt},
|
||||
{ BLE_HCI_LE_SUBEV_PERIODIC_ADV_SYNC_LOST,
|
||||
ble_hs_hci_evt_le_periodic_adv_sync_lost},
|
||||
{ BLE_HCI_LE_SUBEV_RD_REM_USED_FEAT,
|
||||
ble_hs_hci_evt_le_rd_rem_used_feat_complete },
|
||||
{ BLE_HCI_LE_SUBEV_SCAN_TIMEOUT,
|
||||
@@ -226,7 +233,8 @@ ble_hs_hci_evt_enc_key_refresh(uint8_t event_code, uint8_t *data, int len)
|
||||
}
|
||||
|
||||
static int
|
||||
ble_hs_hci_evt_num_completed_pkts(uint8_t event_code, uint8_t *data, int len)
|
||||
ble_hs_hci_evt_num_completed_pkts(uint8_t event_code, uint8_t *data,
|
||||
int len)
|
||||
{
|
||||
struct ble_hs_conn *conn;
|
||||
uint16_t num_pkts;
|
||||
@@ -501,8 +509,9 @@ ble_hs_hci_evt_le_dir_adv_rpt(uint8_t subevent, uint8_t *data, int len)
|
||||
}
|
||||
|
||||
static int
|
||||
ble_hs_hci_evt_le_rd_rem_used_feat_complete(uint8_t subevent, uint8_t *data,
|
||||
int len)
|
||||
ble_hs_hci_evt_le_rd_rem_used_feat_complete(uint8_t subevent,
|
||||
uint8_t *data,
|
||||
int len)
|
||||
{
|
||||
struct hci_le_rd_rem_supp_feat_complete evt;
|
||||
|
||||
@@ -614,6 +623,76 @@ ble_hs_hci_evt_le_ext_adv_rpt(uint8_t subevent, uint8_t *data, int len)
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int
|
||||
ble_hs_hci_evt_le_periodic_adv_sync_estab(uint8_t subevent, uint8_t *data,
|
||||
int len)
|
||||
{
|
||||
#if MYNEWT_VAL(BLE_EXT_ADV) && MYNEWT_VAL(BLE_PERIODIC_ADV)
|
||||
struct hci_le_subev_periodic_adv_sync_estab evt;
|
||||
|
||||
if (len < BLE_HCI_LE_PERIODIC_ADV_SYNC_ESTAB_LEN) {
|
||||
return BLE_HS_ECONTROLLER;
|
||||
}
|
||||
|
||||
evt.status = data[1];
|
||||
evt.sync_handle = get_le16(data + 2);
|
||||
evt.sid = data[4];
|
||||
evt.adv_addr_type = data[5];
|
||||
memcpy(evt.adv_addr, &data[6], 6);
|
||||
evt.adv_phy = data[12];
|
||||
evt.per_adv_ival = get_le16(data + 13);
|
||||
evt.adv_clk_accuracy = data[15];
|
||||
|
||||
ble_gap_rx_peroidic_adv_sync_estab(&evt);
|
||||
#endif
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int
|
||||
ble_hs_hci_evt_le_periodic_adv_rpt(uint8_t subevent, uint8_t *data,
|
||||
int len)
|
||||
{
|
||||
#if MYNEWT_VAL(BLE_EXT_ADV) && MYNEWT_VAL(BLE_PERIODIC_ADV)
|
||||
struct hci_le_subev_periodic_adv_rpt evt;
|
||||
|
||||
if (len < BLE_HCI_LE_PERIODIC_ADV_RPT_LEN) {
|
||||
return BLE_HS_EBADDATA;
|
||||
}
|
||||
|
||||
evt.sync_handle = get_le16(data + 1);
|
||||
evt.tx_power = data[3];
|
||||
evt.rssi = data[4];
|
||||
evt.data_status = data[6];
|
||||
evt.data_length = data[7];
|
||||
memcpy(evt.data, &data[8], evt.data_length);
|
||||
|
||||
ble_gap_rx_periodic_adv_rpt(&evt);
|
||||
#endif
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int
|
||||
ble_hs_hci_evt_le_periodic_adv_sync_lost(uint8_t subevent, uint8_t *data,
|
||||
int len)
|
||||
{
|
||||
#if MYNEWT_VAL(BLE_EXT_ADV) && MYNEWT_VAL(BLE_PERIODIC_ADV)
|
||||
struct hci_le_subev_periodic_adv_sync_lost evt;
|
||||
|
||||
if (len < BLE_HCI_LE_PERIODIC_ADV_SYNC_LOST_LEN) {
|
||||
return BLE_HS_EBADDATA;
|
||||
}
|
||||
|
||||
evt.sync_handle = get_le16(data + 1);
|
||||
|
||||
ble_gap_rx_periodic_adv_sync_lost(&evt);
|
||||
|
||||
#endif
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
static int
|
||||
ble_hs_hci_evt_le_scan_timeout(uint8_t subevent, uint8_t *data, int len)
|
||||
{
|
||||
|
||||
@@ -235,6 +235,48 @@ ble_hs_hci_cmd_build_le_ext_adv_params(uint8_t handle,
|
||||
int
|
||||
ble_hs_hci_cmd_build_le_ext_adv_remove(uint8_t handle,
|
||||
uint8_t *cmd, int cmd_len);
|
||||
|
||||
#if MYNEWT_VAL(BLE_PERIODIC_ADV)
|
||||
int
|
||||
ble_hs_hci_cmd_build_le_periodic_adv_params(uint8_t handle,
|
||||
const struct hci_periodic_adv_params *params,
|
||||
uint8_t *cmd, int cmd_len);
|
||||
|
||||
int
|
||||
ble_hs_hci_cmd_build_le_periodic_adv_enable(uint8_t enable,
|
||||
uint8_t handle,
|
||||
uint8_t *cmd, int cmd_len);
|
||||
|
||||
int
|
||||
ble_hs_hci_cmd_build_le_periodic_adv_data(uint8_t handle, uint8_t operation,
|
||||
struct os_mbuf *data,
|
||||
uint8_t data_len,
|
||||
uint8_t *cmd, int cmd_len);
|
||||
int
|
||||
ble_hs_hci_cmd_build_le_periodic_adv_create_sync(uint8_t filter_policy,
|
||||
uint8_t adv_sid,
|
||||
uint8_t adv_add_type,
|
||||
const uint8_t *adv_addr,
|
||||
uint16_t skip,
|
||||
uint16_t sync_timeout,
|
||||
uint8_t *cmd, int cmd_len);
|
||||
|
||||
int
|
||||
ble_hs_hci_cmd_build_le_periodic_adv_terminate_sync(uint16_t sync_handle,
|
||||
uint8_t *cmd, int cmd_len);
|
||||
|
||||
int
|
||||
ble_hs_hci_cmd_build_le_add_dev_to_periodic_adv_list(uint8_t adv_add_type,
|
||||
const uint8_t *adv_addr,
|
||||
uint8_t adv_sid,
|
||||
uint8_t *cmd, int cmd_len);
|
||||
int
|
||||
ble_hs_hci_cmd_build_le_rem_dev_from_periodic_adv_list(uint8_t adv_add_type,
|
||||
const uint8_t *adv_addr,
|
||||
uint8_t adv_sid,
|
||||
uint8_t *cmd, int cmd_len);
|
||||
#endif
|
||||
|
||||
#endif
|
||||
|
||||
int ble_hs_hci_cmd_build_le_enh_recv_test(uint8_t rx_chan, uint8_t phy,
|
||||
|
||||
@@ -0,0 +1,230 @@
|
||||
/*
|
||||
* 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.
|
||||
*/
|
||||
|
||||
#include <string.h>
|
||||
#include <errno.h>
|
||||
#include "syscfg/syscfg.h"
|
||||
#include "os/os.h"
|
||||
#include "host/ble_hs_id.h"
|
||||
#include "ble_hs_priv.h"
|
||||
|
||||
static SLIST_HEAD(, ble_hs_periodic_sync) ble_hs_periodic_sync_handles;
|
||||
static struct os_mempool ble_hs_periodic_sync_pool;
|
||||
|
||||
static os_membuf_t ble_hs_psync_elem_mem[
|
||||
OS_MEMPOOL_SIZE(MYNEWT_VAL(BLE_MAX_PERIODIC_SCANNING_SM),
|
||||
sizeof (struct ble_hs_periodic_sync))
|
||||
];
|
||||
|
||||
int
|
||||
ble_hs_periodic_sync_can_alloc(void)
|
||||
{
|
||||
#if !MYNEWT_VAL(BLE_PERIODIC_ADV)
|
||||
return 0;
|
||||
#endif
|
||||
|
||||
return (ble_hs_periodic_sync_pool.mp_num_free >= 1);
|
||||
}
|
||||
|
||||
struct ble_hs_periodic_sync *
|
||||
ble_hs_periodic_sync_alloc(void)
|
||||
{
|
||||
#if !MYNEWT_VAL(BLE_PERIODIC_ADV)
|
||||
return NULL;
|
||||
#endif
|
||||
|
||||
struct ble_hs_periodic_sync *psync;
|
||||
|
||||
psync = os_memblock_get(&ble_hs_periodic_sync_pool);
|
||||
if (psync == NULL) {
|
||||
goto err;
|
||||
}
|
||||
memset(psync, 0, sizeof *psync);
|
||||
|
||||
return psync;
|
||||
|
||||
err:
|
||||
ble_hs_periodic_sync_free(psync);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
void
|
||||
ble_hs_periodic_sync_free(struct ble_hs_periodic_sync *psync)
|
||||
{
|
||||
#if !MYNEWT_VAL(BLE_PERIODIC_ADV)
|
||||
return;
|
||||
#endif
|
||||
|
||||
int rc;
|
||||
if (psync == NULL) {
|
||||
return;
|
||||
}
|
||||
|
||||
#if MYNEWT_VAL(BLE_HS_DEBUG)
|
||||
memset(psync, 0xff, sizeof *psync);
|
||||
#endif
|
||||
rc = os_memblock_put(&ble_hs_periodic_sync_pool, psync);
|
||||
BLE_HS_DBG_ASSERT_EVAL(rc == 0);
|
||||
}
|
||||
|
||||
void
|
||||
ble_hs_periodic_sync_insert(struct ble_hs_periodic_sync *psync)
|
||||
{
|
||||
#if !MYNEWT_VAL(BLE_PERIODIC_ADV)
|
||||
return;
|
||||
#endif
|
||||
|
||||
BLE_HS_DBG_ASSERT(ble_hs_locked_by_cur_task());
|
||||
|
||||
BLE_HS_DBG_ASSERT_EVAL(
|
||||
ble_hs_periodic_sync_find(psync->sync_handle) == NULL);
|
||||
|
||||
SLIST_INSERT_HEAD(&ble_hs_periodic_sync_handles, psync, bhc_next);
|
||||
}
|
||||
|
||||
void
|
||||
ble_hs_periodic_sync_remove(struct ble_hs_periodic_sync *psync)
|
||||
{
|
||||
#if !MYNEWT_VAL(BLE_PERIODIC_ADV)
|
||||
return;
|
||||
#endif
|
||||
|
||||
BLE_HS_DBG_ASSERT(ble_hs_locked_by_cur_task());
|
||||
|
||||
SLIST_REMOVE(&ble_hs_periodic_sync_handles,
|
||||
psync,
|
||||
ble_hs_periodic_sync,
|
||||
bhc_next);
|
||||
}
|
||||
|
||||
struct ble_hs_periodic_sync *
|
||||
ble_hs_periodic_sync_find(uint16_t sync_handle)
|
||||
{
|
||||
#if !MYNEWT_VAL(BLE_PERIODIC_ADV)
|
||||
return NULL;
|
||||
#endif
|
||||
|
||||
struct ble_hs_periodic_sync *psync;
|
||||
|
||||
BLE_HS_DBG_ASSERT(ble_hs_locked_by_cur_task());
|
||||
|
||||
SLIST_FOREACH(psync, &ble_hs_periodic_sync_handles, bhc_next) {
|
||||
if (psync->sync_handle == sync_handle) {
|
||||
return psync;
|
||||
}
|
||||
}
|
||||
|
||||
return NULL;
|
||||
}
|
||||
|
||||
struct ble_hs_periodic_sync *
|
||||
ble_hs_periodic_sync_find_assert(uint16_t sync_handle)
|
||||
{
|
||||
struct ble_hs_periodic_sync *psync;
|
||||
|
||||
psync = ble_hs_periodic_sync_find(sync_handle);
|
||||
BLE_HS_DBG_ASSERT(psync != NULL);
|
||||
|
||||
return psync;
|
||||
}
|
||||
|
||||
struct ble_hs_periodic_sync *
|
||||
ble_hs_periodic_sync_find_by_adv_addr(const ble_addr_t *addr)
|
||||
{
|
||||
#if !MYNEWT_VAL(BLE_PERIODIC_ADV)
|
||||
return NULL;
|
||||
#endif
|
||||
|
||||
struct ble_hs_periodic_sync *psync;
|
||||
|
||||
BLE_HS_DBG_ASSERT(ble_hs_locked_by_cur_task());
|
||||
|
||||
if (!addr) {
|
||||
return NULL;
|
||||
}
|
||||
|
||||
SLIST_FOREACH(psync, &ble_hs_periodic_sync_handles, bhc_next) {
|
||||
if (ble_addr_cmp(&psync->advertiser_addr, addr) == 0) {
|
||||
return psync;
|
||||
}
|
||||
}
|
||||
|
||||
return NULL;
|
||||
}
|
||||
|
||||
struct ble_hs_periodic_sync *
|
||||
ble_hs_periodic_sync_find_by_adv_sid(uint16_t sid)
|
||||
{
|
||||
#if !MYNEWT_VAL(BLE_PERIODIC_ADV)
|
||||
return 0;
|
||||
#endif
|
||||
|
||||
struct ble_hs_periodic_sync *psync;
|
||||
|
||||
BLE_HS_DBG_ASSERT(ble_hs_locked_by_cur_task());
|
||||
|
||||
SLIST_FOREACH(psync, &ble_hs_periodic_sync_handles, bhc_next) {
|
||||
if (psync->adv_sid == sid) {
|
||||
return psync;
|
||||
}
|
||||
}
|
||||
|
||||
return NULL;
|
||||
}
|
||||
|
||||
int
|
||||
ble_hs_periodic_sync_exists(uint16_t sync_handle)
|
||||
{
|
||||
#if !MYNEWT_VAL(BLE_PERIODIC_ADV)
|
||||
return 0;
|
||||
#endif
|
||||
return ble_hs_periodic_sync_find(sync_handle) != NULL;
|
||||
}
|
||||
|
||||
/**
|
||||
* Retrieves the first periodic discovery handle in the list.
|
||||
*/
|
||||
struct ble_hs_periodic_sync *
|
||||
ble_hs_periodic_sync_first(void)
|
||||
{
|
||||
#if !MYNEWT_VAL(BLE_PERIODIC_ADV)
|
||||
return NULL;
|
||||
#endif
|
||||
|
||||
BLE_HS_DBG_ASSERT(ble_hs_locked_by_cur_task());
|
||||
return SLIST_FIRST(&ble_hs_periodic_sync_handles);
|
||||
}
|
||||
|
||||
int
|
||||
ble_hs_periodic_sync_init(void)
|
||||
{
|
||||
int rc;
|
||||
|
||||
rc = os_mempool_init(&ble_hs_periodic_sync_pool,
|
||||
MYNEWT_VAL(BLE_MAX_PERIODIC_SCANNING_SM),
|
||||
sizeof (struct ble_hs_periodic_sync),
|
||||
ble_hs_psync_elem_mem, "ble_hs_periodic_disc_pool");
|
||||
if (rc != 0) {
|
||||
return BLE_HS_EOS;
|
||||
}
|
||||
|
||||
SLIST_INIT(&ble_hs_periodic_sync_handles);
|
||||
|
||||
return 0;
|
||||
}
|
||||
@@ -0,0 +1,61 @@
|
||||
/*
|
||||
* 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_HS_PERIODIC_DISC_
|
||||
#define H_BLE_HS_PERIODIC_DISC_
|
||||
|
||||
#include <inttypes.h>
|
||||
#include "os/queue.h"
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
struct ble_hs_periodic_sync {
|
||||
SLIST_ENTRY(ble_hs_periodic_sync) bhc_next;
|
||||
uint16_t sync_handle;
|
||||
uint8_t adv_sid;
|
||||
uint8_t advertiser_addr_type;
|
||||
ble_addr_t advertiser_addr;
|
||||
uint8_t advertiser_phy;
|
||||
uint16_t periodic_adv_itvl;
|
||||
uint8_t advertiser_clock_accuracy;
|
||||
};
|
||||
|
||||
int ble_hs_periodic_sync_can_alloc(void);
|
||||
struct ble_hs_periodic_sync *ble_hs_periodic_sync_alloc(void);
|
||||
void ble_hs_periodic_sync_free(struct ble_hs_periodic_sync *psync);
|
||||
void ble_hs_periodic_sync_insert(struct ble_hs_periodic_sync *psync);
|
||||
void ble_hs_periodic_sync_remove(struct ble_hs_periodic_sync *psync);
|
||||
struct ble_hs_periodic_sync *ble_hs_periodic_sync_find(
|
||||
uint16_t sync_handle);
|
||||
struct ble_hs_periodic_sync *ble_hs_periodic_sync_find_assert(
|
||||
uint16_t sync_handle);
|
||||
struct ble_hs_periodic_sync *ble_hs_periodic_sync_find_by_adv_addr(
|
||||
const ble_addr_t *addr);
|
||||
struct ble_hs_periodic_sync *ble_hs_periodic_sync_find_by_adv_sid(
|
||||
uint16_t sid);
|
||||
int ble_hs_periodic_sync_exists(uint16_t sync_handle);
|
||||
struct ble_hs_periodic_sync *ble_hs_periodic_sync_first(void);
|
||||
int ble_hs_periodic_sync_init(void);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif
|
||||
@@ -30,6 +30,7 @@
|
||||
#include "ble_hs_hci_priv.h"
|
||||
#include "ble_hs_atomic_priv.h"
|
||||
#include "ble_hs_conn_priv.h"
|
||||
#include "ble_hs_periodic_disc_priv.h"
|
||||
#include "ble_hs_atomic_priv.h"
|
||||
#include "ble_hs_mbuf_priv.h"
|
||||
#include "ble_hs_startup_priv.h"
|
||||
|
||||
@@ -256,12 +256,15 @@ ble_hs_startup_le_set_evmask_tx(void)
|
||||
* Enable the following LE events:
|
||||
* 0x0000000000000800 LE PHY Update Complete Event
|
||||
* 0x0000000000001000 LE Extended Advertising Report Event
|
||||
* 0x0000000000002000 LE Periodic Advertising Sync Established Event
|
||||
* 0x0000000000004000 LE Periodic Advertising Report Event
|
||||
* 0x0000000000008000 LE Periodic Advertising Sync Lost Event
|
||||
* 0x0000000000010000 LE Extended Scan Timeout Event
|
||||
* 0x0000000000020000 LE Extended Advertising Set Terminated Event
|
||||
* 0x0000000000040000 LE Scan Request Received Event
|
||||
* 0x0000000000080000 LE Channel Selection Algorithm Event
|
||||
*/
|
||||
mask |= 0x00000000000f1800;
|
||||
mask |= 0x00000000000ff800;
|
||||
}
|
||||
|
||||
ble_hs_hci_cmd_build_le_set_event_mask(mask, buf, sizeof buf);
|
||||
|
||||
@@ -58,10 +58,52 @@ ble_hs_stop_done(int status)
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Terminates all active periodic sync handles
|
||||
*
|
||||
* If there are no active periodic sync handles, signals completion of the
|
||||
* close procedure.
|
||||
*/
|
||||
static int
|
||||
ble_hs_stop_terminate_next_periodic_sync(void)
|
||||
{
|
||||
int rc = 0;
|
||||
#if MYNEWT_VAL(BLE_PERIODIC_ADV)
|
||||
struct ble_hs_periodic_sync *psync;
|
||||
|
||||
while((psync = ble_hs_periodic_sync_first())){
|
||||
/* Terminate sync command waits a command complete event, so there
|
||||
* is no need to wait for GAP event, as the calling thread will be
|
||||
* blocked on the hci semaphore until the command complete is received.
|
||||
*
|
||||
* Also, once the sync is terminated, the psync will be freed and
|
||||
* removed from the list such that the next call to
|
||||
* ble_hs_periodic_sync_first yields the next psync handle
|
||||
*/
|
||||
rc = ble_gap_periodic_adv_terminate_sync(psync->sync_handle);
|
||||
|
||||
if (!rc){
|
||||
BLE_HS_LOG(ERROR,
|
||||
"ble_hs_stop: failed to terminate connection; rc=%d\n",
|
||||
rc);
|
||||
ble_hs_stop_done(rc);
|
||||
}
|
||||
}
|
||||
|
||||
#endif
|
||||
/* No more active periodic sync handles (Or periodic advertising
|
||||
* is not supported), Signal completion of the stop procedure.
|
||||
*/
|
||||
ble_hs_stop_done(0);
|
||||
|
||||
return rc;
|
||||
}
|
||||
|
||||
/**
|
||||
* Terminates the first open connection.
|
||||
*
|
||||
* If there are no open connections, signals completion of the close procedure.
|
||||
* If there are no open connections, Check for any active periodic sync
|
||||
* handles.
|
||||
*/
|
||||
static void
|
||||
ble_hs_stop_terminate_next_conn(void)
|
||||
@@ -71,8 +113,8 @@ ble_hs_stop_terminate_next_conn(void)
|
||||
|
||||
handle = ble_hs_atomic_first_conn_handle();
|
||||
if (handle == BLE_HS_CONN_HANDLE_NONE) {
|
||||
/* No open connections. Signal completion of the stop procedure. */
|
||||
ble_hs_stop_done(0);
|
||||
/* No open connections. Check for any active periodic sync */
|
||||
ble_hs_stop_terminate_next_periodic_sync();
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
@@ -149,19 +149,19 @@ extern "C" {
|
||||
#define BLE_HCI_OCF_LE_RD_NUM_OF_ADV_SETS (0x003B)
|
||||
#define BLE_HCI_OCF_LE_REMOVE_ADV_SET (0x003C)
|
||||
#define BLE_HCI_OCF_LE_CLEAR_ADV_SETS (0x003D)
|
||||
#define BLE_HCI_OCF_LE_SET_PER_ADV_PARAMS (0x003E)
|
||||
#define BLE_HCI_OCF_LE_SET_PER_ADV_DATA (0x003F)
|
||||
#define BLE_HCI_OCF_LE_SET_PER_ADV_ENABLE (0x0040)
|
||||
#define BLE_HCI_OCF_LE_SET_PERIODIC_ADV_PARAMS (0x003E)
|
||||
#define BLE_HCI_OCF_LE_SET_PERIODIC_ADV_DATA (0x003F)
|
||||
#define BLE_HCI_OCF_LE_SET_PERIODIC_ADV_ENABLE (0x0040)
|
||||
#define BLE_HCI_OCF_LE_SET_EXT_SCAN_PARAM (0x0041)
|
||||
#define BLE_HCI_OCF_LE_SET_EXT_SCAN_ENABLE (0x0042)
|
||||
#define BLE_HCI_OCF_LE_EXT_CREATE_CONN (0x0043)
|
||||
#define BLE_HCI_OCF_LE_PER_ADV_CREATE_SYNC (0x0044)
|
||||
#define BLE_HCI_OCF_LE_PER_ADV_CREATE_SYNC_CANCEL (0x0045)
|
||||
#define BLE_HCI_OCF_LE_PER_ADV_TERM_SYNC (0x0046)
|
||||
#define BLE_HCI_OCF_LE_ADD_DEV_TO_PER_ADV_LIST (0x0047)
|
||||
#define BLE_HCI_OCF_LE_REM_DEV_FROM_PER_ADV_LIST (0x0048)
|
||||
#define BLE_HCI_OCF_LE_CLEAR_PER_ADV_LIST (0x0049)
|
||||
#define BLE_HCI_OCF_LE_RD_PER_ADV_LIST_SIZE (0x004A)
|
||||
#define BLE_HCI_OCF_LE_PERIODIC_ADV_CREATE_SYNC (0x0044)
|
||||
#define BLE_HCI_OCF_LE_PERIODIC_ADV_CREATE_SYNC_CANCEL (0x0045)
|
||||
#define BLE_HCI_OCF_LE_PERIODIC_ADV_TERM_SYNC (0x0046)
|
||||
#define BLE_HCI_OCF_LE_ADD_DEV_TO_PERIODIC_ADV_LIST (0x0047)
|
||||
#define BLE_HCI_OCF_LE_REM_DEV_FROM_PERIODIC_ADV_LIST (0x0048)
|
||||
#define BLE_HCI_OCF_LE_CLEAR_PERIODIC_ADV_LIST (0x0049)
|
||||
#define BLE_HCI_OCF_LE_RD_PERIODIC_ADV_LIST_SIZE (0x004A)
|
||||
#define BLE_HCI_OCF_LE_RD_TRANSMIT_POWER (0x004B)
|
||||
#define BLE_HCI_OCF_LE_RD_RF_PATH_COMPENSATION (0x004C)
|
||||
#define BLE_HCI_OCF_LE_WR_RF_PATH_COMPENSATION (0x004D)
|
||||
@@ -522,21 +522,18 @@ extern "C" {
|
||||
#define BLE_HCI_SET_EXT_ADV_DATA_HDR_LEN (4)
|
||||
|
||||
#define BLE_HCI_LE_SET_EXT_ADV_DATA_LEN BLE_HCI_VARIABLE_LEN
|
||||
#define BLE_HCI_LE_SET_EXT_ADV_DATA_OPER_INT (0)
|
||||
#define BLE_HCI_LE_SET_EXT_ADV_DATA_OPER_FIRST (1)
|
||||
#define BLE_HCI_LE_SET_EXT_ADV_DATA_OPER_LAST (2)
|
||||
#define BLE_HCI_LE_SET_EXT_ADV_DATA_OPER_COMPLETE (3)
|
||||
#define BLE_HCI_LE_SET_EXT_ADV_DATA_OPER_UNCHANGED (4)
|
||||
#define BLE_HCI_LE_SET_DATA_OPER_INT (0)
|
||||
#define BLE_HCI_LE_SET_DATA_OPER_FIRST (1)
|
||||
#define BLE_HCI_LE_SET_DATA_OPER_LAST (2)
|
||||
#define BLE_HCI_LE_SET_DATA_OPER_COMPLETE (3)
|
||||
#define BLE_HCI_LE_SET_DATA_OPER_UNCHANGED (4)
|
||||
|
||||
/* --- LE set extended scan response data (OCF 0x0038) */
|
||||
#define BLE_HCI_MAX_EXT_SCAN_RSP_DATA_LEN (251)
|
||||
#define BLE_HCI_SET_EXT_SCAN_RSP_DATA_HDR_LEN (4)
|
||||
|
||||
#define BLE_HCI_LE_SET_EXT_SCAN_RSP_DATA_LEN BLE_HCI_VARIABLE_LEN
|
||||
#define BLE_HCI_LE_SET_EXT_SCAN_RSP_DATA_OPER_INT (0)
|
||||
#define BLE_HCI_LE_SET_EXT_SCAN_RSP_DATA_OPER_FIRST (1)
|
||||
#define BLE_HCI_LE_SET_EXT_SCAN_RSP_DATA_OPER_LAST (2)
|
||||
#define BLE_HCI_LE_SET_EXT_SCAN_RSP_DATA_OPER_COMPLETE (3)
|
||||
|
||||
|
||||
/* --- LE set extended advertising enable (OCF 0x0039) */
|
||||
#define BLE_HCI_LE_SET_EXT_ADV_ENABLE_LEN BLE_HCI_VARIABLE_LEN
|
||||
@@ -551,13 +548,18 @@ extern "C" {
|
||||
#define BLE_HCI_RD_NR_SUP_ADV_SETS (1)
|
||||
|
||||
/* --- LE set periodic advertising parameters (OCF 0x003E) */
|
||||
#define BLE_HCI_LE_SET_PER_ADV_PARAMS_LEN (7)
|
||||
#define BLE_HCI_LE_SET_PERIODIC_ADV_PARAMS_LEN (7)
|
||||
#define BLE_HCI_LE_SET_PERIODIC_ADV_PROP_INC_TX_PWR (0x0040)
|
||||
|
||||
/* --- LE set periodic advertising data (OCF 0x003F) */
|
||||
#define BLE_HCI_LE_SET_PER_ADV_DATA_LEN BLE_HCI_VARIABLE_LEN
|
||||
#define BLE_HCI_LE_SET_PERIODIC_ADV_DATA_LEN BLE_HCI_VARIABLE_LEN
|
||||
#define BLE_HCI_MAX_PERIODIC_ADV_DATA_LEN (252)
|
||||
#define BLE_HCI_SET_PERIODIC_ADV_DATA_HDR_LEN (3)
|
||||
|
||||
|
||||
|
||||
/* --- LE periodic advertising enable (OCF 0x0040) */
|
||||
#define BLE_HCI_LE_SET_PER_ADV_ENABLE_LEN (2)
|
||||
#define BLE_HCI_LE_SET_PERIODIC_ADV_ENABLE_LEN (2)
|
||||
|
||||
/* --- LE set extended scan parameters (OCF 0x0041) */
|
||||
#define BLE_HCI_LE_SET_EXT_SCAN_PARAM_LEN BLE_HCI_VARIABLE_LEN
|
||||
@@ -572,16 +574,16 @@ extern "C" {
|
||||
#define BLE_HCI_LE_EXT_CREATE_CONN_BASE_LEN (10)
|
||||
|
||||
/* --- LE periodic advertising create sync (OCF 0x0044) */
|
||||
#define BLE_HCI_LE_PER_ADV_CREATE_SYNC_LEN (14)
|
||||
#define BLE_HCI_LE_PERIODIC_ADV_CREATE_SYNC_LEN (14)
|
||||
|
||||
/* --- LE periodic advertising terminate (OCF 0x0046) */
|
||||
#define BLE_HCI_LE_PER_ADV_TERM_SYNC_LEN (2)
|
||||
#define BLE_HCI_LE_PERIODIC_ADV_TERM_SYNC_LEN (2)
|
||||
|
||||
/* --- LE add device to periodic advertising list (OCF 0x0047) */
|
||||
#define BLE_HCI_LE_ADD_DEV_TO_PER_ADV_LIST_LEN (8)
|
||||
#define BLE_HCI_LE_ADD_DEV_TO_PERIODIC_ADV_LIST_LEN (8)
|
||||
|
||||
/* --- LE remove device from periodic advertising list (OCF 0x0048) */
|
||||
#define BLE_HCI_LE_REM_DEV_FROM_PER_ADV_LIST_LEN (8)
|
||||
#define BLE_HCI_LE_REM_DEV_FROM_PERIODIC_ADV_LIST_LEN (8)
|
||||
|
||||
/* --- LE write RF path (OCF 0x004D) */
|
||||
#define BLE_HCI_LE_WR_RF_PATH_COMPENSATION_LEN (4)
|
||||
@@ -685,9 +687,9 @@ extern "C" {
|
||||
#define BLE_HCI_LE_SUBEV_DIRECT_ADV_RPT (0x0B)
|
||||
#define BLE_HCI_LE_SUBEV_PHY_UPDATE_COMPLETE (0x0C)
|
||||
#define BLE_HCI_LE_SUBEV_EXT_ADV_RPT (0x0D)
|
||||
#define BLE_HCI_LE_SUBEV_PER_ADV_SYNC_ESTAB (0x0E)
|
||||
#define BLE_HCI_LE_SUBEV_PER_ADV_RPT (0x0F)
|
||||
#define BLE_HCI_LE_SUBEV_PER_ADV_SYNC_LOST (0x10)
|
||||
#define BLE_HCI_LE_SUBEV_PERIODIC_ADV_SYNC_ESTAB (0x0E)
|
||||
#define BLE_HCI_LE_SUBEV_PERIODIC_ADV_RPT (0x0F)
|
||||
#define BLE_HCI_LE_SUBEV_PERIODIC_ADV_SYNC_LOST (0x10)
|
||||
#define BLE_HCI_LE_SUBEV_SCAN_TIMEOUT (0x11)
|
||||
#define BLE_HCI_LE_SUBEV_ADV_SET_TERMINATED (0x12)
|
||||
#define BLE_HCI_LE_SUBEV_SCAN_REQ_RCVD (0x13)
|
||||
@@ -780,6 +782,15 @@ extern "C" {
|
||||
/* LE PHY update complete event (sub event 0x0C) */
|
||||
#define BLE_HCI_LE_PHY_UPD_LEN (6)
|
||||
|
||||
/* LE Periodic Advertising Sync Established Event (sub event 0x0e) */
|
||||
#define BLE_HCI_LE_PERIODIC_ADV_SYNC_ESTAB_LEN (16)
|
||||
|
||||
/* LE Periodic Advertising Report Event (sub event 0x0f) */
|
||||
#define BLE_HCI_LE_PERIODIC_ADV_RPT_LEN (8)
|
||||
|
||||
/* LE Periodic Advertising Sync Lost Event (sub event 0x10) */
|
||||
#define BLE_HCI_LE_PERIODIC_ADV_SYNC_LOST_LEN (3)
|
||||
|
||||
/* LE Scan Timeout Event (sub event 0x11) */
|
||||
#define BLE_HCI_LE_SUBEV_SCAN_TIMEOUT_LEN (1)
|
||||
|
||||
@@ -990,8 +1001,17 @@ struct hci_le_subev_ext_adv_rpt {
|
||||
struct hci_ext_adv_report_param params[0];
|
||||
} __attribute__((packed));
|
||||
|
||||
#if MYNEWT_VAL(BLE_PERIODIC_ADV)
|
||||
/* Periodic Advertising Parameters */
|
||||
struct hci_periodic_adv_params
|
||||
{
|
||||
uint16_t min_interval;
|
||||
uint16_t max_interval;
|
||||
uint16_t properties;
|
||||
};
|
||||
|
||||
/* LE Periodic Advertising Sync Established Event */
|
||||
struct hci_le_subev_per_adv_sync_estab {
|
||||
struct hci_le_subev_periodic_adv_sync_estab {
|
||||
uint8_t status;
|
||||
uint16_t sync_handle;
|
||||
uint8_t sid;
|
||||
@@ -1003,20 +1023,20 @@ struct hci_le_subev_per_adv_sync_estab {
|
||||
} __attribute__((packed));
|
||||
|
||||
/* LE Periodic Advertising Report Event */
|
||||
struct hci_le_subev_per_adv_rpt {
|
||||
struct hci_le_subev_periodic_adv_rpt {
|
||||
uint16_t sync_handle;
|
||||
uint8_t tx_power;
|
||||
int8_t rssi;
|
||||
uint8_t _unused;
|
||||
uint8_t data_status;
|
||||
uint8_t data_length;
|
||||
uint8_t data[0];
|
||||
} __attribute__((packed));
|
||||
|
||||
/* LE Periodic Advertising Sync Lost Event */
|
||||
struct hci_le_subev_per_adv_sync_lost {
|
||||
struct hci_le_subev_periodic_adv_sync_lost {
|
||||
uint16_t sync_handle;
|
||||
} __attribute__((packed));
|
||||
#endif
|
||||
|
||||
/* LE Advertising Set Terminated Event */
|
||||
struct hci_le_subev_adv_set_terminated {
|
||||
|
||||
@@ -34,6 +34,11 @@ syscfg.defs:
|
||||
BLE_MAX_CONNECTIONS:
|
||||
description: 'The maximum number of concurrent connections.'
|
||||
value: 1
|
||||
BLE_MAX_PERIODIC_SCANNING_SM:
|
||||
description: >
|
||||
The maximum number of concurrent periodic syncs that can
|
||||
be created
|
||||
value: 1
|
||||
BLE_WHITELIST:
|
||||
description: >
|
||||
Enables the BLE whitelist for controlling who to connect to or
|
||||
@@ -50,6 +55,10 @@ syscfg.defs:
|
||||
description: >
|
||||
This enables extended advertising feature.
|
||||
value: 0
|
||||
BLE_PERIODIC_ADV:
|
||||
description: >
|
||||
This enables periodic advertising feature.
|
||||
value: 0
|
||||
BLE_EXT_ADV_MAX_SIZE:
|
||||
description: >
|
||||
This allows to configure maximum size of advertising data and
|
||||
|
||||
@@ -247,6 +247,10 @@
|
||||
#define MYNEWT_VAL_BLE_MAX_CONNECTIONS (1)
|
||||
#endif
|
||||
|
||||
#ifndef MYNEWT_VAL_BLE_MAX_PERIODIC_SCANNING_SM
|
||||
#define MYNEWT_VAL_BLE_MAX_PERIODIC_SCANNING_SM (0)
|
||||
#endif
|
||||
|
||||
#ifndef MYNEWT_VAL_BLE_MULTI_ADV_INSTANCES
|
||||
#define MYNEWT_VAL_BLE_MULTI_ADV_INSTANCES (0)
|
||||
#endif
|
||||
|
||||
@@ -247,6 +247,10 @@
|
||||
#define MYNEWT_VAL_BLE_MAX_CONNECTIONS (1)
|
||||
#endif
|
||||
|
||||
#ifndef MYNEWT_VAL_BLE_MAX_PERIODIC_SCANNING_SM
|
||||
#define MYNEWT_VAL_BLE_MAX_PERIODIC_SCANNING_SM (0)
|
||||
#endif
|
||||
|
||||
#ifndef MYNEWT_VAL_BLE_MULTI_ADV_INSTANCES
|
||||
#define MYNEWT_VAL_BLE_MULTI_ADV_INSTANCES (0)
|
||||
#endif
|
||||
|
||||
@@ -50,6 +50,7 @@ NIMBLE_SRC := \
|
||||
$(filter-out $(NIMBLE_IGNORE), $(wildcard $(NIMBLE_ROOT)/nimble/host/services/lls/src/*.c)) \
|
||||
$(filter-out $(NIMBLE_IGNORE), $(wildcard $(NIMBLE_ROOT)/nimble/host/services/tps/src/*.c)) \
|
||||
$(filter-out $(NIMBLE_IGNORE), $(wildcard $(NIMBLE_ROOT)/nimble/host/store/ram/src/*.c)) \
|
||||
$(NIMBLE_ROOT)/nimble/host/src/ble_hs_periodic_disc.c \
|
||||
$(NULL)
|
||||
|
||||
ifneq (,$(NIMBLE_CFG_CONTROLLER))
|
||||
|
||||
@@ -389,6 +389,10 @@
|
||||
#define MYNEWT_VAL_BLE_MAX_CONNECTIONS (1)
|
||||
#endif
|
||||
|
||||
#ifndef MYNEWT_VAL_BLE_MAX_PERIODIC_SCANNING_SM
|
||||
#define MYNEWT_VAL_BLE_MAX_PERIODIC_SCANNING_SM (0)
|
||||
#endif
|
||||
|
||||
#ifndef MYNEWT_VAL_BLE_MULTI_ADV_INSTANCES
|
||||
#define MYNEWT_VAL_BLE_MULTI_ADV_INSTANCES (0)
|
||||
#endif
|
||||
@@ -418,6 +422,11 @@
|
||||
#define MYNEWT_VAL_BLE_ATT_PREFERRED_MTU (256)
|
||||
#endif
|
||||
|
||||
|
||||
#ifndef MYNEWT_VAL_BLE_PERIODIC_ADV
|
||||
#define MYNEWT_VAL_BLE_PERIODIC_ADV (0)
|
||||
#endif
|
||||
|
||||
#ifndef MYNEWT_VAL_BLE_ATT_SVR_FIND_INFO
|
||||
#define MYNEWT_VAL_BLE_ATT_SVR_FIND_INFO (1)
|
||||
#endif
|
||||
|
||||
@@ -410,6 +410,10 @@
|
||||
#define MYNEWT_VAL_BLE_MAX_CONNECTIONS (1)
|
||||
#endif
|
||||
|
||||
#ifndef MYNEWT_VAL_BLE_MAX_PERIODIC_SCANNING_SM
|
||||
#define MYNEWT_VAL_BLE_MAX_PERIODIC_SCANNING_SM (0)
|
||||
#endif
|
||||
|
||||
#ifndef MYNEWT_VAL_BLE_MULTI_ADV_INSTANCES
|
||||
#define MYNEWT_VAL_BLE_MULTI_ADV_INSTANCES (0)
|
||||
#endif
|
||||
|
||||
Reference in New Issue
Block a user