mirror of
https://github.com/espressif/esp-nimble.git
synced 2026-09-16 05:59:55 +00:00
Merge pull request #671 from sjanc/ext_adv_host
Extended Advertising API X-Original-Commit: 50a0295e04f7e9a88ad4e5f5f4ae6c1e3d73dfbb
This commit is contained in:
@@ -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,
|
||||
|
||||
@@ -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
File diff suppressed because it is too large
Load Diff
@@ -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
@@ -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)
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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)
|
||||
{
|
||||
|
||||
@@ -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,
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
|
||||
@@ -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. */
|
||||
|
||||
@@ -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());
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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);
|
||||
}
|
||||
|
||||
|
||||
@@ -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));
|
||||
|
||||
@@ -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)
|
||||
|
||||
Reference in New Issue
Block a user