Merge pull request #671 from sjanc/ext_adv_host

Extended Advertising API

X-Original-Commit: 50a0295e04f7e9a88ad4e5f5f4ae6c1e3d73dfbb
This commit is contained in:
Szymon Janc
2017-11-23 10:30:18 +01:00
committed by GitHub
15 changed files with 1045 additions and 415 deletions
+41 -3
View File
@@ -372,11 +372,19 @@ struct ble_gap_event {
/**
* The reason the advertise procedure stopped. Typical reason
* codes are:
* o 0: Duration expired.
* o 0: Terminated due to connection.
* o BLE_HS_ETIMEOUT: Duration expired.
* o BLE_HS_EPREEMPTED: Host aborted procedure to configure a
* peer's identity.
*/
int reason;
#if MYNEWT_VAL(BLE_EXT_ADV)
/** Advertising instance */
uint8_t instance;
/** The handle of the relevant connection - valid if reason=0 */
uint16_t conn_handle;
#endif
} adv_complete;
/**
@@ -676,8 +684,38 @@ int ble_gap_adv_set_fields(const struct ble_hs_adv_fields *rsp_fields);
int ble_gap_adv_rsp_set_fields(const struct ble_hs_adv_fields *rsp_fields);
#if MYNEWT_VAL(BLE_EXT_ADV)
int ble_gap_adv_set_tx_power(int8_t tx_power);
int ble_gap_adv_set_phys(uint8_t primary_phy, uint8_t secondary_phy);
struct ble_gap_ext_adv_params {
unsigned int connectable:1;
unsigned int scannable:1;
unsigned int directed:1;
unsigned int high_duty_directed:1;
unsigned int legacy_pdu:1;
unsigned int anonymous:1;
unsigned int include_tx_power:1;
unsigned int scan_req_notif:1;
uint32_t itvl_min;
uint32_t itvl_max;
uint8_t channel_map;
uint8_t own_addr_type;
ble_addr_t peer;
uint8_t filter_policy;
uint8_t primary_phy;
uint8_t secondary_phy;
int8_t tx_power;
uint8_t sid;
};
int ble_gap_ext_adv_configure(uint8_t instance,
const struct ble_gap_ext_adv_params *params,
int8_t *selected_tx_power,
ble_gap_event_fn *cb, void *cb_arg);
int ble_gap_ext_adv_set_addr(uint8_t instance, const ble_addr_t *addr);
int ble_gap_ext_adv_start(uint8_t instance, int duration, int max_events);
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);
#endif
int ble_gap_disc(uint8_t own_addr_type, int32_t duration_ms,
+3
View File
@@ -158,6 +158,9 @@ struct ble_hs_adv_fields {
#define BLE_HS_ADV_SVC_DATA_UUID128_MIN_LEN 16
int ble_hs_adv_set_fields_mbuf(const struct ble_hs_adv_fields *adv_fields,
struct os_mbuf *om);
int ble_hs_adv_set_fields(const struct ble_hs_adv_fields *adv_fields,
uint8_t *dst, uint8_t *dst_len, uint8_t max_len);
+749 -266
View File
File diff suppressed because it is too large Load Diff
+2 -1
View File
@@ -77,10 +77,11 @@ extern STATS_SECT_DECL(ble_gap_stats) ble_gap_stats;
#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);
#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);
int ble_gap_rx_conn_complete(struct hci_le_conn_complete *evt);
int ble_gap_rx_conn_complete(struct hci_le_conn_complete *evt, uint8_t instance);
void ble_gap_rx_disconn_complete(struct hci_disconn_complete *evt);
void ble_gap_rx_update_complete(struct hci_le_conn_upd_complete *evt);
void ble_gap_rx_param_req(struct hci_le_conn_param_req *evt);
+161 -71
View File
@@ -34,8 +34,21 @@ static ble_uuid128_t ble_hs_adv_uuids128[BLE_HS_ADV_MAX_FIELD_SZ / 16];
static int
ble_hs_adv_set_hdr(uint8_t type, uint8_t data_len, uint8_t max_len,
uint8_t *dst, uint8_t *dst_len)
uint8_t *dst, uint8_t *dst_len, struct os_mbuf *om)
{
int rc;
if (om ) {
data_len++;
rc = os_mbuf_append(om, &data_len, sizeof(data_len));
if (rc) {
return rc;
}
return os_mbuf_append(om, &type, sizeof(type));
}
if (*dst_len + 2 + data_len > max_len) {
return BLE_HS_EMSGSIZE;
}
@@ -48,46 +61,67 @@ ble_hs_adv_set_hdr(uint8_t type, uint8_t data_len, uint8_t max_len,
return 0;
}
int
ble_hs_adv_set_flat(uint8_t type, int data_len, const void *data,
uint8_t *dst, uint8_t *dst_len, uint8_t max_len)
static int
ble_hs_adv_set_flat_mbuf(uint8_t type, int data_len, const void *data,
uint8_t *dst, uint8_t *dst_len, uint8_t max_len,
struct os_mbuf *om)
{
#if !NIMBLE_BLE_ADVERTISE
return BLE_HS_ENOTSUP;
#endif
int rc;
BLE_HS_DBG_ASSERT(data_len > 0);
rc = ble_hs_adv_set_hdr(type, data_len, max_len, dst, dst_len);
rc = ble_hs_adv_set_hdr(type, data_len, max_len, dst, dst_len, om);
if (rc != 0) {
return rc;
}
if (om) {
return os_mbuf_append(om, data, data_len);
}
memcpy(dst + *dst_len, data, data_len);
*dst_len += data_len;
return 0;
}
int
ble_hs_adv_set_flat(uint8_t type, int data_len, const void *data,
uint8_t *dst, uint8_t *dst_len, uint8_t max_len)
{
#if !NIMBLE_BLE_ADVERTISE
return BLE_HS_ENOTSUP;
#endif
return ble_hs_adv_set_flat_mbuf(type, data_len, data, dst, dst_len, max_len,
NULL);
}
static int
ble_hs_adv_set_array_uuid16(uint8_t type, uint8_t num_elems,
const ble_uuid16_t *elems, uint8_t *dst,
uint8_t *dst_len, uint8_t max_len)
uint8_t *dst_len, uint8_t max_len,
struct os_mbuf *om)
{
int rc;
int i;
rc = ble_hs_adv_set_hdr(type, num_elems * 2, max_len, dst,
dst_len);
dst_len, om);
if (rc != 0) {
return rc;
}
for (i = 0; i < num_elems; i++) {
ble_uuid_flat(&elems[i].u, dst + *dst_len);
*dst_len += 2;
if (om) {
rc = ble_uuid_to_mbuf(&elems[i].u, om);
if (rc) {
return rc;
}
} else {
ble_uuid_flat(&elems[i].u, dst + *dst_len);
*dst_len += 2;
}
}
return 0;
@@ -96,13 +130,15 @@ ble_hs_adv_set_array_uuid16(uint8_t type, uint8_t num_elems,
static int
ble_hs_adv_set_array_uuid32(uint8_t type, uint8_t num_elems,
const ble_uuid32_t *elems, uint8_t *dst,
uint8_t *dst_len, uint8_t max_len)
uint8_t *dst_len, uint8_t max_len,
struct os_mbuf *om)
{
uint32_t uuid_le;
int rc;
int i;
rc = ble_hs_adv_set_hdr(type, num_elems * 4, max_len, dst,
dst_len);
dst_len, om);
if (rc != 0) {
return rc;
}
@@ -112,8 +148,16 @@ ble_hs_adv_set_array_uuid32(uint8_t type, uint8_t num_elems,
* 128-bit as ATT requires. In AD, 32-bit UUID shall be written as an
* actual 32-bit value.
*/
put_le32(dst + *dst_len, elems[i].value);
*dst_len += 4;
if (om) {
uuid_le = htole32(elems[i].value);
rc = os_mbuf_append(om, &uuid_le, sizeof(uuid_le));
if (rc) {
return rc;
}
} else {
put_le32(dst + *dst_len, elems[i].value);
*dst_len += 4;
}
}
return 0;
@@ -122,20 +166,28 @@ ble_hs_adv_set_array_uuid32(uint8_t type, uint8_t num_elems,
static int
ble_hs_adv_set_array_uuid128(uint8_t type, uint8_t num_elems,
const ble_uuid128_t *elems, uint8_t *dst,
uint8_t *dst_len, uint8_t max_len)
uint8_t *dst_len, uint8_t max_len,
struct os_mbuf *om)
{
int rc;
int i;
rc = ble_hs_adv_set_hdr(type, num_elems * 16, max_len, dst,
dst_len);
dst_len, om);
if (rc != 0) {
return rc;
}
for (i = 0; i < num_elems; i++) {
ble_uuid_flat(&elems[i].u, dst + *dst_len);
*dst_len += 16;
if (om) {
rc = ble_uuid_to_mbuf(&elems[i].u, om);
if (rc) {
return rc;
}
} else {
ble_uuid_flat(&elems[i].u, dst + *dst_len);
*dst_len += 16;
}
}
return 0;
@@ -143,33 +195,39 @@ ble_hs_adv_set_array_uuid128(uint8_t type, uint8_t num_elems,
static int
ble_hs_adv_set_array16(uint8_t type, uint8_t num_elems, const uint16_t *elems,
uint8_t *dst, uint8_t *dst_len, uint8_t max_len)
uint8_t *dst, uint8_t *dst_len, uint8_t max_len,
struct os_mbuf *om)
{
uint16_t tmp;
int rc;
int i;
rc = ble_hs_adv_set_hdr(type, num_elems * sizeof *elems, max_len, dst,
dst_len);
dst_len, om);
if (rc != 0) {
return rc;
}
for (i = 0; i < num_elems; i++) {
put_le16(dst + *dst_len, elems[i]);
*dst_len += sizeof elems[i];
if (om) {
tmp = htole16(elems[i]);
rc = os_mbuf_append(om, &tmp, sizeof(tmp));
if (rc) {
return rc;
}
} else {
put_le16(dst + *dst_len, elems[i]);
*dst_len += sizeof elems[i];
}
}
return 0;
}
/**
* Converts a high-level set of fields to a byte buffer.
*
* @return 0 on success; nonzero on failure.
*/
int
ble_hs_adv_set_fields(const struct ble_hs_adv_fields *adv_fields,
uint8_t *dst, uint8_t *dst_len, uint8_t max_len)
static int
adv_set_fields(const struct ble_hs_adv_fields *adv_fields,
uint8_t *dst, uint8_t *dst_len, uint8_t max_len,
struct os_mbuf *om)
{
#if !NIMBLE_BLE_ADVERTISE
return BLE_HS_ENOTSUP;
@@ -179,7 +237,9 @@ ble_hs_adv_set_fields(const struct ble_hs_adv_fields *adv_fields,
int8_t tx_pwr_lvl;
int rc;
*dst_len = 0;
if (dst_len) {
*dst_len = 0;
}
/*** 0x01 - Flags. */
/* The application has two options concerning the flags field:
@@ -190,8 +250,9 @@ ble_hs_adv_set_fields(const struct ble_hs_adv_fields *adv_fields,
* of specifying option 1 vs. 2 is sound.
*/
if (adv_fields->flags != 0) {
rc = ble_hs_adv_set_flat(BLE_HS_ADV_TYPE_FLAGS, 1, &adv_fields->flags,
dst, dst_len, max_len);
rc = ble_hs_adv_set_flat_mbuf(BLE_HS_ADV_TYPE_FLAGS, 1,
&adv_fields->flags, dst, dst_len,
max_len, om);
if (rc != 0) {
return rc;
@@ -208,7 +269,7 @@ ble_hs_adv_set_fields(const struct ble_hs_adv_fields *adv_fields,
rc = ble_hs_adv_set_array_uuid16(type, adv_fields->num_uuids16,
adv_fields->uuids16, dst, dst_len,
max_len);
max_len, om);
if (rc != 0) {
return rc;
}
@@ -224,7 +285,7 @@ ble_hs_adv_set_fields(const struct ble_hs_adv_fields *adv_fields,
rc = ble_hs_adv_set_array_uuid32(type, adv_fields->num_uuids32,
adv_fields->uuids32, dst, dst_len,
max_len);
max_len, om);
if (rc != 0) {
return rc;
}
@@ -240,7 +301,7 @@ ble_hs_adv_set_fields(const struct ble_hs_adv_fields *adv_fields,
rc = ble_hs_adv_set_array_uuid128(type, adv_fields->num_uuids128,
adv_fields->uuids128, dst, dst_len,
max_len);
max_len, om);
if (rc != 0) {
return rc;
}
@@ -254,8 +315,9 @@ ble_hs_adv_set_fields(const struct ble_hs_adv_fields *adv_fields,
type = BLE_HS_ADV_TYPE_INCOMP_NAME;
}
rc = ble_hs_adv_set_flat(type, adv_fields->name_len, adv_fields->name,
dst, dst_len, max_len);
rc = ble_hs_adv_set_flat_mbuf(type, adv_fields->name_len,
adv_fields->name, dst, dst_len, max_len,
om);
if (rc != 0) {
return rc;
}
@@ -275,8 +337,8 @@ ble_hs_adv_set_fields(const struct ble_hs_adv_fields *adv_fields,
tx_pwr_lvl = adv_fields->tx_pwr_lvl;
}
rc = ble_hs_adv_set_flat(BLE_HS_ADV_TYPE_TX_PWR_LVL, 1, &tx_pwr_lvl,
dst, dst_len, max_len);
rc = ble_hs_adv_set_flat_mbuf(BLE_HS_ADV_TYPE_TX_PWR_LVL, 1,
&tx_pwr_lvl, dst, dst_len, max_len, om);
if (rc != 0) {
return rc;
}
@@ -284,10 +346,10 @@ ble_hs_adv_set_fields(const struct ble_hs_adv_fields *adv_fields,
/*** 0x12 - Slave connection interval range. */
if (adv_fields->slave_itvl_range != NULL) {
rc = ble_hs_adv_set_flat(BLE_HS_ADV_TYPE_SLAVE_ITVL_RANGE,
BLE_HS_ADV_SLAVE_ITVL_RANGE_LEN,
adv_fields->slave_itvl_range, dst, dst_len,
max_len);
rc = ble_hs_adv_set_flat_mbuf(BLE_HS_ADV_TYPE_SLAVE_ITVL_RANGE,
BLE_HS_ADV_SLAVE_ITVL_RANGE_LEN,
adv_fields->slave_itvl_range, dst,
dst_len, max_len, om);
if (rc != 0) {
return rc;
}
@@ -295,10 +357,10 @@ ble_hs_adv_set_fields(const struct ble_hs_adv_fields *adv_fields,
/*** 0x16 - Service data - 16-bit UUID. */
if (adv_fields->svc_data_uuid16 != NULL) {
rc = ble_hs_adv_set_flat(BLE_HS_ADV_TYPE_SVC_DATA_UUID16,
adv_fields->svc_data_uuid16_len,
adv_fields->svc_data_uuid16, dst, dst_len,
max_len);
rc = ble_hs_adv_set_flat_mbuf(BLE_HS_ADV_TYPE_SVC_DATA_UUID16,
adv_fields->svc_data_uuid16_len,
adv_fields->svc_data_uuid16, dst, dst_len,
max_len, om);
if (rc != 0) {
return rc;
}
@@ -308,11 +370,11 @@ ble_hs_adv_set_fields(const struct ble_hs_adv_fields *adv_fields,
if (adv_fields->public_tgt_addr != NULL &&
adv_fields->num_public_tgt_addrs != 0) {
rc = ble_hs_adv_set_flat(BLE_HS_ADV_TYPE_PUBLIC_TGT_ADDR,
rc = ble_hs_adv_set_flat_mbuf(BLE_HS_ADV_TYPE_PUBLIC_TGT_ADDR,
BLE_HS_ADV_PUBLIC_TGT_ADDR_ENTRY_LEN *
adv_fields->num_public_tgt_addrs,
adv_fields->public_tgt_addr, dst, dst_len,
max_len);
max_len, om);
if (rc != 0) {
return rc;
}
@@ -320,10 +382,10 @@ ble_hs_adv_set_fields(const struct ble_hs_adv_fields *adv_fields,
/*** 0x19 - Appearance. */
if (adv_fields->appearance_is_present) {
rc = ble_hs_adv_set_flat(BLE_HS_ADV_TYPE_APPEARANCE,
BLE_HS_ADV_APPEARANCE_LEN,
&adv_fields->appearance, dst, dst_len,
max_len);
rc = ble_hs_adv_set_flat_mbuf(BLE_HS_ADV_TYPE_APPEARANCE,
BLE_HS_ADV_APPEARANCE_LEN,
&adv_fields->appearance, dst, dst_len,
max_len, om);
if (rc != 0) {
return rc;
}
@@ -333,7 +395,7 @@ ble_hs_adv_set_fields(const struct ble_hs_adv_fields *adv_fields,
if (adv_fields->adv_itvl_is_present) {
rc = ble_hs_adv_set_array16(BLE_HS_ADV_TYPE_ADV_ITVL, 1,
&adv_fields->adv_itvl, dst, dst_len,
max_len);
max_len, om);
if (rc != 0) {
return rc;
}
@@ -341,10 +403,10 @@ ble_hs_adv_set_fields(const struct ble_hs_adv_fields *adv_fields,
/*** 0x20 - Service data - 32-bit UUID. */
if (adv_fields->svc_data_uuid32 != NULL) {
rc = ble_hs_adv_set_flat(BLE_HS_ADV_TYPE_SVC_DATA_UUID32,
adv_fields->svc_data_uuid32_len,
adv_fields->svc_data_uuid32, dst, dst_len,
max_len);
rc = ble_hs_adv_set_flat_mbuf(BLE_HS_ADV_TYPE_SVC_DATA_UUID32,
adv_fields->svc_data_uuid32_len,
adv_fields->svc_data_uuid32, dst, dst_len,
max_len, om);
if (rc != 0) {
return rc;
}
@@ -352,10 +414,10 @@ ble_hs_adv_set_fields(const struct ble_hs_adv_fields *adv_fields,
/*** 0x21 - Service data - 128-bit UUID. */
if (adv_fields->svc_data_uuid128 != NULL) {
rc = ble_hs_adv_set_flat(BLE_HS_ADV_TYPE_SVC_DATA_UUID128,
adv_fields->svc_data_uuid128_len,
adv_fields->svc_data_uuid128, dst, dst_len,
max_len);
rc = ble_hs_adv_set_flat_mbuf(BLE_HS_ADV_TYPE_SVC_DATA_UUID128,
adv_fields->svc_data_uuid128_len,
adv_fields->svc_data_uuid128, dst,
dst_len, max_len, om);
if (rc != 0) {
return rc;
}
@@ -363,8 +425,9 @@ ble_hs_adv_set_fields(const struct ble_hs_adv_fields *adv_fields,
/*** 0x24 - URI. */
if (adv_fields->uri != NULL) {
rc = ble_hs_adv_set_flat(BLE_HS_ADV_TYPE_URI, adv_fields->uri_len,
adv_fields->uri, dst, dst_len, max_len);
rc = ble_hs_adv_set_flat_mbuf(BLE_HS_ADV_TYPE_URI, adv_fields->uri_len,
adv_fields->uri, dst, dst_len, max_len,
om);
if (rc != 0) {
return rc;
}
@@ -372,9 +435,10 @@ ble_hs_adv_set_fields(const struct ble_hs_adv_fields *adv_fields,
/*** 0xff - Manufacturer specific data. */
if (adv_fields->mfg_data != NULL) {
rc = ble_hs_adv_set_flat(BLE_HS_ADV_TYPE_MFG_DATA,
adv_fields->mfg_data_len,
adv_fields->mfg_data, dst, dst_len, max_len);
rc = ble_hs_adv_set_flat_mbuf(BLE_HS_ADV_TYPE_MFG_DATA,
adv_fields->mfg_data_len,
adv_fields->mfg_data,
dst, dst_len, max_len, om);
if (rc != 0) {
return rc;
}
@@ -383,6 +447,32 @@ ble_hs_adv_set_fields(const struct ble_hs_adv_fields *adv_fields,
return 0;
}
/**
* Converts a high-level set of fields to a byte buffer.
*
* @return 0 on success; nonzero on failure.
*/
int
ble_hs_adv_set_fields(const struct ble_hs_adv_fields *adv_fields,
uint8_t *dst, uint8_t *dst_len, uint8_t max_len)
{
#if !NIMBLE_BLE_ADVERTISE
return BLE_HS_ENOTSUP;
#endif
return adv_set_fields(adv_fields, dst, dst_len, max_len, NULL);
}
int
ble_hs_adv_set_fields_mbuf(const struct ble_hs_adv_fields *adv_fields,
struct os_mbuf *om)
{
#if !NIMBLE_BLE_ADVERTISE
return BLE_HS_ENOTSUP;
#endif
return adv_set_fields(adv_fields, NULL, NULL, 0, om);
}
static int
ble_hs_adv_parse_uuids16(struct ble_hs_adv_fields *adv_fields,
const uint8_t *data, uint8_t data_len)
+13 -20
View File
@@ -1471,8 +1471,8 @@ ble_hs_hci_cmd_build_le_ext_adv_set_random_addr(uint8_t handle,
int
ble_hs_hci_cmd_build_le_ext_adv_data(uint8_t handle, uint8_t operation,
uint8_t frag_pref,
const uint8_t *data, uint8_t data_len,
uint8_t frag_pref, struct os_mbuf *data,
uint8_t data_len,
uint8_t *cmd, int cmd_len)
{
BLE_HS_DBG_ASSERT(cmd_len >= 4 + data_len);
@@ -1481,24 +1481,7 @@ ble_hs_hci_cmd_build_le_ext_adv_data(uint8_t handle, uint8_t operation,
cmd[1] = operation;
cmd[2] = frag_pref;
cmd[3] = data_len;
memcpy(cmd + 4, data, data_len);
return 0;
}
int
ble_hs_hci_cmd_build_le_ext_adv_scan_rsp(uint8_t handle, uint8_t operation,
uint8_t frag_pref,
const uint8_t *data, uint8_t data_len,
uint8_t *cmd, int cmd_len)
{
BLE_HS_DBG_ASSERT(cmd_len >= 4 + data_len);
cmd[0] = handle;
cmd[1] = operation;
cmd[2] = frag_pref;
cmd[3] = data_len;
memcpy(cmd + 4, data, data_len);
os_mbuf_copydata(data, 0, data_len, cmd + 4);
return 0;
}
@@ -1560,6 +1543,16 @@ ble_hs_hci_cmd_build_le_ext_adv_params(uint8_t handle,
return 0;
}
int
ble_hs_hci_cmd_build_le_ext_adv_remove(uint8_t handle,
uint8_t *cmd, int cmd_len)
{
BLE_HS_DBG_ASSERT(cmd_len >= BLE_HCI_LE_REMOVE_ADV_SET_LEN);
cmd[0] = handle;
return 0;
}
#endif
static int
+40 -6
View File
@@ -50,6 +50,7 @@ static ble_hs_hci_evt_le_fn ble_hs_hci_evt_le_dir_adv_rpt;
static ble_hs_hci_evt_le_fn ble_hs_hci_evt_le_phy_update_complete;
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_adv_set_terminated;
/* Statistics */
struct host_hci_stats
@@ -101,6 +102,8 @@ static const struct ble_hs_hci_evt_le_dispatch_entry
{ BLE_HCI_LE_SUBEV_EXT_ADV_RPT, ble_hs_hci_evt_le_ext_adv_rpt },
{ BLE_HCI_LE_SUBEV_RD_REM_USED_FEAT,
ble_hs_hci_evt_le_rd_rem_used_feat_complete },
{ BLE_HCI_LE_SUBEV_ADV_SET_TERMINATED,
ble_hs_hci_evt_le_adv_set_terminated },
};
#define BLE_HS_HCI_EVT_LE_DISPATCH_SZ \
@@ -300,12 +303,15 @@ ble_hs_hci_evt_le_meta(uint8_t event_code, uint8_t *data, int len)
return 0;
}
#if MYNEWT_VAL(BLE_EXT_ADV)
static struct hci_le_conn_complete pend_conn_complete;
#endif
static int
ble_hs_hci_evt_le_conn_complete(uint8_t subevent, uint8_t *data, int len)
{
struct hci_le_conn_complete evt;
int extended_offset = 0;
int rc;
if (len < BLE_HCI_LE_CONN_COMPLETE_LEN) {
return BLE_HS_ECONTROLLER;
@@ -348,12 +354,14 @@ ble_hs_hci_evt_le_conn_complete(uint8_t subevent, uint8_t *data, int len)
}
}
rc = ble_gap_rx_conn_complete(&evt);
if (rc != 0) {
return rc;
#if MYNEWT_VAL(BLE_EXT_ADV)
if (evt.role == BLE_HCI_LE_CONN_COMPLETE_ROLE_SLAVE) {
/* store this until we get set terminated event with adv handle */
memcpy(&pend_conn_complete, &evt, sizeof(evt));
return 0;
}
return 0;
#endif
return ble_gap_rx_conn_complete(&evt, 0xff);
}
static int
@@ -594,6 +602,32 @@ 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_adv_set_terminated(uint8_t subevent, uint8_t *data, int len)
{
#if MYNEWT_VAL(BLE_EXT_ADV)
struct hci_le_adv_set_terminated evt;
if (len < BLE_HCI_LE_SUBEV_ADV_SET_TERMINATED_LEN) {
return BLE_HS_ECONTROLLER;
}
evt.subevent_code = data[0];
evt.status = data[1];
evt.adv_handle = data[2];
evt.conn_handle = get_le16(data + 3);
evt.completed_events = data[5];
if (evt.status == 0) {
/* ignore return code as we need to terminate advertising set anyway */
ble_gap_rx_conn_complete(&pend_conn_complete, evt.adv_handle);
}
ble_gap_rx_adv_set_terminated(&evt);
#endif
return 0;
}
static int
ble_hs_hci_evt_le_conn_upd_complete(uint8_t subevent, uint8_t *data, int len)
{
+6 -10
View File
@@ -212,20 +212,12 @@ ble_hs_hci_cmd_build_le_ext_adv_set_random_addr(uint8_t handle,
const uint8_t *addr,
uint8_t *cmd, int cmd_len);
int
ble_hs_hci_cmd_build_le_ext_adv_data(uint8_t handle, uint8_t operation,
uint8_t frag_pref,
const uint8_t *data, uint8_t data_len,
uint8_t frag_pref, struct os_mbuf *data,
uint8_t data_len,
uint8_t *cmd, int cmd_len);
int
ble_hs_hci_cmd_build_le_ext_adv_scan_rsp(uint8_t handle, uint8_t operation,
uint8_t frag_pref,
const uint8_t *data, uint8_t data_len,
uint8_t *cmd, int cmd_len);
int
ble_hs_hci_cmd_build_le_ext_adv_enable(uint8_t enable, uint8_t sets_num,
const struct hci_ext_adv_set *sets,
@@ -235,6 +227,10 @@ int
ble_hs_hci_cmd_build_le_ext_adv_params(uint8_t handle,
const struct hci_ext_adv_params *params,
uint8_t *cmd, int cmd_len);
int
ble_hs_hci_cmd_build_le_ext_adv_remove(uint8_t handle,
uint8_t *cmd, int cmd_len);
#endif
int ble_hs_hci_cmd_build_le_enh_recv_test(uint8_t rx_chan, uint8_t phy,
-24
View File
@@ -126,12 +126,7 @@ ble_hs_hci_util_read_rssi(uint16_t conn_handle, int8_t *out_rssi)
int
ble_hs_hci_util_set_random_addr(const uint8_t *addr)
{
#if MYNEWT_VAL(BLE_EXT_ADV)
/* this buffer is larger and can handle both commands */
uint8_t buf[BLE_HCI_LE_SET_ADV_SET_RND_ADDR_LEN];
#else
uint8_t buf[BLE_HCI_SET_RAND_ADDR_LEN];
#endif
int rc;
/* set the address in the controller */
@@ -148,25 +143,6 @@ ble_hs_hci_util_set_random_addr(const uint8_t *addr)
return rc;
}
#if MYNEWT_VAL(BLE_EXT_ADV)
/* TODO
* Since we currently support only 1 instance we can set random address
* here. For now advertising handle is hardcoded.
*/
rc = ble_hs_hci_cmd_build_le_ext_adv_set_random_addr(0, addr, 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_ADV_SET_RND_ADDR),
buf, sizeof(buf));
if (rc != 0) {
return rc;
}
#endif
return 0;
}
+6 -6
View File
@@ -860,7 +860,7 @@ TEST_CASE(ble_gap_test_case_conn_gen_good)
evt.connection_handle = 2;
evt.role = BLE_HCI_LE_CONN_COMPLETE_ROLE_MASTER;
memcpy(evt.peer_addr, peer_addr.val, 6);
rc = ble_gap_rx_conn_complete(&evt);
rc = ble_gap_rx_conn_complete(&evt, 0);
TEST_ASSERT(rc == 0);
TEST_ASSERT(!ble_gap_master_in_progress());
@@ -1008,7 +1008,7 @@ TEST_CASE(ble_gap_test_case_conn_gen_fail_evt)
evt.status = BLE_ERR_CONN_ACCEPT_TMO;
evt.role = BLE_HCI_LE_CONN_COMPLETE_ROLE_MASTER;
rc = ble_gap_rx_conn_complete(&evt);
rc = ble_gap_rx_conn_complete(&evt, 0);
TEST_ASSERT_FATAL(rc == 0);
/* Ensure failed connect was reported to application. */
@@ -1055,7 +1055,7 @@ ble_gap_test_util_conn_cancel(uint8_t hci_status)
memset(&evt, 0, sizeof evt);
evt.subevent_code = BLE_HCI_LE_SUBEV_CONN_COMPLETE;
evt.status = BLE_ERR_UNK_CONN_ID;
rc = ble_gap_rx_conn_complete(&evt);
rc = ble_gap_rx_conn_complete(&evt, 0);
TEST_ASSERT(rc == 0);
TEST_ASSERT(!ble_gap_master_in_progress());
@@ -1134,7 +1134,7 @@ TEST_CASE(ble_gap_test_case_conn_cancel_ctlr_fail)
evt.connection_handle = 2;
evt.role = BLE_HCI_LE_CONN_COMPLETE_ROLE_MASTER;
memcpy(evt.peer_addr, peer_addr, 6);
rc = ble_gap_rx_conn_complete(&evt);
rc = ble_gap_rx_conn_complete(&evt, 0);
TEST_ASSERT(rc == 0);
TEST_ASSERT(!ble_gap_master_in_progress());
@@ -1492,7 +1492,7 @@ ble_gap_test_util_adv(uint8_t own_addr_type,
evt.connection_handle = 2;
evt.role = BLE_HCI_LE_CONN_COMPLETE_ROLE_SLAVE;
memcpy(evt.peer_addr, peer_addr->val, 6);
rc = ble_gap_rx_conn_complete(&evt);
rc = ble_gap_rx_conn_complete(&evt, 0);
TEST_ASSERT(rc == 0);
if (connect_status == 0 ||
@@ -2773,7 +2773,7 @@ ble_gap_test_util_conn_timeout(int32_t duration_ms)
memset(&evt, 0, sizeof evt);
evt.subevent_code = BLE_HCI_LE_SUBEV_CONN_COMPLETE;
evt.status = BLE_ERR_UNK_CONN_ID;
rc = ble_gap_rx_conn_complete(&evt);
rc = ble_gap_rx_conn_complete(&evt, 0);
TEST_ASSERT_FATAL(rc == 0);
/* Ensure the GAP event was triggered. */
+3 -3
View File
@@ -70,7 +70,7 @@ TEST_CASE(ble_hs_conn_test_direct_connect_success)
evt.connection_handle = 2;
evt.role = BLE_HCI_LE_CONN_COMPLETE_ROLE_MASTER;
memcpy(evt.peer_addr, addr.val, 6);
rc = ble_gap_rx_conn_complete(&evt);
rc = ble_gap_rx_conn_complete(&evt, 0);
TEST_ASSERT(rc == 0);
TEST_ASSERT(!ble_gap_master_in_progress());
@@ -127,7 +127,7 @@ TEST_CASE(ble_hs_conn_test_direct_connectable_success)
evt.connection_handle = 2;
evt.role = BLE_HCI_LE_CONN_COMPLETE_ROLE_SLAVE;
memcpy(evt.peer_addr, addr.val, 6);
rc = ble_gap_rx_conn_complete(&evt);
rc = ble_gap_rx_conn_complete(&evt, 0);
TEST_ASSERT(rc == 0);
TEST_ASSERT(!ble_gap_master_in_progress());
TEST_ASSERT(!ble_gap_adv_active());
@@ -192,7 +192,7 @@ TEST_CASE(ble_hs_conn_test_undirect_connectable_success)
evt.connection_handle = 2;
evt.role = BLE_HCI_LE_CONN_COMPLETE_ROLE_SLAVE;
memcpy(evt.peer_addr, addr.val, 6);
rc = ble_gap_rx_conn_complete(&evt);
rc = ble_gap_rx_conn_complete(&evt, 0);
TEST_ASSERT(rc == 0);
TEST_ASSERT(!ble_gap_master_in_progress());
TEST_ASSERT(!ble_gap_adv_active());
+1 -1
View File
@@ -242,7 +242,7 @@ ble_hs_test_util_create_rpa_conn(uint16_t handle, uint8_t own_addr_type,
memcpy(evt.local_rpa, our_rpa, 6);
memcpy(evt.peer_rpa, peer_rpa, 6);
rc = ble_gap_rx_conn_complete(&evt);
rc = ble_gap_rx_conn_complete(&evt, 0);
TEST_ASSERT(rc == 0);
evt2.subevent_code = BLE_HCI_LE_SUBEV_RD_REM_USED_FEAT;
+1 -1
View File
@@ -558,7 +558,7 @@ ble_hs_test_util_hci_rx_conn_cancel_evt(void)
evt.status = BLE_ERR_UNK_CONN_ID;
evt.role = BLE_HCI_LE_CONN_COMPLETE_ROLE_MASTER;
rc = ble_gap_rx_conn_complete(&evt);
rc = ble_gap_rx_conn_complete(&evt, 0);
TEST_ASSERT_FATAL(rc == 0);
}
+3 -3
View File
@@ -154,7 +154,7 @@ ble_gap_direct_connect_test_task_handler(void *arg)
evt.status = BLE_ERR_SUCCESS;
evt.connection_handle = 2;
memcpy(evt.peer_addr, addr.val, 6);
rc = ble_gap_rx_conn_complete(&evt);
rc = ble_gap_rx_conn_complete(&evt, 0);
TEST_ASSERT(rc == 0);
/* The connection should now be created. */
@@ -316,7 +316,7 @@ ble_gap_terminate_test_task_handler(void *arg)
conn_evt.status = BLE_ERR_SUCCESS;
conn_evt.connection_handle = 1;
memcpy(conn_evt.peer_addr, addr1.val, 6);
rc = ble_gap_rx_conn_complete(&conn_evt);
rc = ble_gap_rx_conn_complete(&conn_evt, 0);
TEST_ASSERT(rc == 0);
ble_hs_test_util_connect(BLE_OWN_ADDR_PUBLIC,
@@ -330,7 +330,7 @@ ble_gap_terminate_test_task_handler(void *arg)
conn_evt.status = BLE_ERR_SUCCESS;
conn_evt.connection_handle = 2;
memcpy(conn_evt.peer_addr, addr2.val, 6);
rc = ble_gap_rx_conn_complete(&conn_evt);
rc = ble_gap_rx_conn_complete(&conn_evt, 0);
TEST_ASSERT(rc == 0);
TEST_ASSERT_FATAL(ble_os_test_misc_conn_exists(1));
+16
View File
@@ -491,6 +491,9 @@ extern "C" {
#define BLE_HCI_LE_SET_EXT_ADV_PROP_LEGACY_NONCONN (0x0010)
/* --- LE set extended advertising data (OCF 0x0037) */
#define BLE_HCI_MAX_EXT_ADV_DATA_LEN (251)
#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)
@@ -499,6 +502,9 @@ extern "C" {
#define BLE_HCI_LE_SET_EXT_ADV_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)
@@ -1046,6 +1052,16 @@ struct hci_le_phy_upd_complete
uint8_t rx_phy;
};
/* LE Advertising Set Terminated subevent*/
struct hci_le_adv_set_terminated
{
uint8_t subevent_code;
uint8_t status;
uint8_t adv_handle;
uint16_t conn_handle;
uint8_t completed_events;
};
#define BLE_HCI_DATA_HDR_SZ 4
#define BLE_HCI_DATA_HANDLE(handle_pb_bc) (((handle_pb_bc) & 0x0fff) >> 0)
#define BLE_HCI_DATA_PB(handle_pb_bc) (((handle_pb_bc) & 0x3000) >> 12)